I'm no Citrix expert but a coworker asked one day for an easy way to remove Windows profiles on a bunch of XenApp servers. �This is the result.

This script allows the user to select a particular farm and one or more usernames. �Based off of that it will then go out, discover all the servers in that particular farm and attempt to remove the user's profiles from every server.

Download this script on the Technet Script Repository.

<# 
        .SYNOPSIS 
        This script was designed to remove one or more Windows profiles from groups of Citrix XenApp servers. 
        Sometimes when a particular user has a problem with logging into a Citrix session their Windows profile 
        must be removed from all XenApp servers in a particular farm.  This script allows the user to specify 
        a username and a farm name to remove the profile across all servers.  
 
        This script uses PSRemoting to connect to the farm's ZDC server and runs a disovery of all servers 
        in a specified farm.  It then enumerates all profiles on each of those servers by querying the ProfileList 
        registry key and based off of that it then finds and removes the user's profile across all of the servers. 
 
        Before running this script for the first time be sure to associate your ZDC servers with particular farms 
        on line 78 so that the script can accurately find all servers in the farm. 
        .NOTES 
        Filename:    Remove-CitrixUserProfile.ps1 
        Version:     1.0.0 
        .EXAMPLE 
        PS> .\Remove-CitrixUserProfile -Username bdole -Farm Farm1 
 
        This example will enumerate all servers in the Farm1 farm and attempt to remove all user profile for bdole on 
        each server in that farm. 
        .EXAMPLE 
        PS> 'bdole','bjones','ajeffrey' | .\Remove-CitrixUserProfile.ps1 -Farm Farm2 
 
        This script will remove the user profiles bdole, bjones and ajeffrey from all Xenapp servers in the farm 
        Farm2. 
        .PARAMETER Username 
        One or more usernames (in a comma-separed format) that you'd like removed. 
        .PARAMETER Farm 
        The name of the farm that contains the servers you'd like to remove the user profile from. 
#> 
[CmdletBinding(SupportsShouldProcess)] 
param ( 
    [Parameter(ValueFromPipeline,Mandatory)] 
    [string[]]$Username, 
    [Parameter(Mandatory)] 
    [string]$Farm 
) 
 
begin { 
    Set-StrictMode -Version Latest 
     
    function Get-CitrixXaServer { 
        param ( 
            [string]$ZdcServer   
        ) 
        $Block = { Add-PSSnapin Citrix*; Get-Xaserver | Where-Object { $_.ElectionPreference -eq 'WorkerMode' } | Select-Object -ExpandProperty ServerName } 
        Invoke-Command -ComputerName $ZdcServer -ScriptBlock $Block  | Sort-Object 
    } 
     
    function Test-MyConnection { 
        param ( 
            [string]$Computername 
        ) 
        try { 
            $oPing = new-object system.net.networkinformation.ping; 
            if (($oPing.Send($ComputerName, 200).Status -eq 'TimedOut')) { 
                $false 
            } 
        } catch { 
            throw "Unable to ping $Computername" 
        } 
    } 
     
    function Get-UserProfile { 
        param ( 
            [string]$XaServer, 
            [string]$UserName 
        ) 
        $Params = @{ 
            'ClassName' = 'Win32_UserProfile' 
        } 
        if ($XaServer -ne 'localhost') { 
            $Params.ComputerName = $XaServer 
        } 
        Get-CimInstance @Params | Where-Object { $_.LocalPath.Split('\')[-1] -match "$UserName$" } 
    } 
     
    ## Before running for the first time, be sure to associate all farms that will be queried 
    ## with the farm's ZDC server.  If you don't do this, things will not go well. 
    $FarmZdcs = @{ 
         
    } 
} 
 
process { 
    Write-Verbose -Message "Finding all XA servers in farm [$Farm]..." 
    if ($FarmZdcs.Count -eq 0) { 
        throw 'No XA servers found in the $FarmZdcs variable' 
    } else { 
        Write-Verbose "Using the ZDC server [$($FarmZdcs[$Farm])]" 
    } 
    $XaServers = Get-CitrixXaServer -ZdcServer $FarmZdcs.$Farm 
    if (-not $XaServers) { 
        throw "No XA servers found in farm [$Farm]" 
    } else { 
        Write-Verbose -Message "Found [$(($XaServers | Measure-Object).Count)] XA servers in farm [$Farm] ([$($XaServers -join ',')])" 
    } 
    foreach ($User in $Username) { 
        foreach ($Server in $XaServers) { 
            try { 
                Write-Verbose -Message "Testing server [$Server] for connectivity..." 
                Test-MyConnection -Computername $Server 
                Write-Verbose -Message "Finding and removing all user profiles for username [$User] on XA server [$Server]..." 
                $UserProfiles = Get-UserProfile -UserName $User -XaServer $Server 
                if (-not $UserProfiles) { 
                    Write-Verbose -Message "No profiles found for user [$User] on XA server [$Server]" 
                } else { 
                    Write-Verbose -Message "Found profiles for user [$User] on XA server [$Server]." 
                    $UserProfiles | foreach { 
                        try { 
                            if ($PsCmdlet.ShouldProcess("User Profile: $($_.LocalPath.Split('\')[-1])")) { 
                                $_ | Remove-CimInstance 
                            } 
                        } catch [exception] { 
                            Write-Warning -Message $_.Exception.Message 
                        } 
                    } 
                } 
            } catch [Exception] { 
                Write-Error -Message $_.Exception.Message     
            } 
        } 
    } 
}

Join the Jar Tippers on Patreon

It takes a lot of time to write detailed blog posts like this one. In a single-income family, this blog is one way I depend on to keep the lights on. I'd be eternally grateful if you could become a Patreon patron today!

Become a Patron!