# encoding: ascii
# api: powershell
# title: Cleanup Citrix Profiles
# description: This code will cleanup local profiles on a server/computer. It needs admin-rights to run.
# version: 0.1
# type: class
# author: DollarUnderscore
# license: CC0
# x-poshcode-id: 4517
# x-archived: 2015-10-17T01:28:28
# x-published: 2015-10-13T10:46:00
#
# It was made to keep Citrix-servers “cleaned up” from profiles that were locked during logoff.
# It might need some changes to work in your enviroment.
# For help, check this link:
# http://dollarunderscore.azurewebsites.net/?p=731
#
#========================================================================
# Generated By: Anders Wahlqvist
# Website: DollarUnderscore (http://dollarunderscore.azurewebsites.net)
#========================================================================

$BaseProfilePath="C:\Users\"
$LocalProfileFolders=gci $BaseProfilePath
$thishost=hostname
$thishostADSI = [ADSI]"WinNT://$thishost,computer"  
$LocalAccountsOnThisHost=$thishostADSI.psbase.Children | Where-Object { $_.psbase.schemaclassname -eq 'user' } | % { $_.Name }
$ExcludedUsers= @()
$LoggedOnUsers = @()
$UsersToIgnore = @()

# Tune performance with $SpeedBrake. Lower is quicker, but uses more CPU.
$SpeedBrake=1

# Add a regex that works for your usernaming standard
$UserNameRegEx="\w"

# Add a list of other accounts you want to exclude
$ExcludedUsers="Public","ctx","svc"

# This get's all the currently logged on users
$LoggedOnUsers=Get-WmiObject win32_process|select name,@{n="owner";e={$_.getowner().user}} | Select-Object Owner -Unique | % { $_.owner }

# Add them all togheter
$UsersToIgnore+=$LoggedOnUsers
$UsersToIgnore+=$ExcludedUsers
$UsersToIgnore+=$LocalAccountsOnThisHost
$UsersToIgnore=$UsersToIgnore | select -Unique

# Start to loop through all the profile folders
foreach ($LocalProfileFolder in $LocalProfileFolders)
{
    # Sleep to prevent CPU load
	sleep -m $SpeedBrake

    # Set this variable to True, it will be changed if it should stay later.
	$ThisProfileShouldBeDeleted=$True

    # This this folder match the username regex?
	if ($LocalProfileFolder.Name -match $UserNameRegEx)
	{
        # Make sure it doesn't match any of the "ignored" users, (logged on ones etc...)
		foreach ($UserToIgnore in $UsersToIgnore)
		{
        # Again, sleep to prevent CPU load.
		sleep -m $SpeedBrake
            # Check if it matches a "ignored" user
			if ($LocalProfileFolder.Name -like "*$UserToIgnore*")
			{
                # If it did, it should not be deleted.
			    $ThisProfileShouldBeDeleted=$False
			}

		}

        # Get the full path
		$CurrentProfileName=$LocalProfileFolder.FullName

        # Check if it should be deleted
		if ($ThisProfileShouldBeDeleted -eq $True)
		{
		    $ProfileToLookFor=$BaseProfilePath + $LocalProfileFolder.Name
		    $ProfileToClean=$ProfileToLookFor -replace "\\","\\"
		    $WMIQuery = $null
		    $WMIQuery=Get-WmiObject Win32_UserProfile  -computer '.' -filter "localpath='$ProfileToClean'"

			if ($WMIQuery -ne $null) {
    		        $TheProfileToDrop=$WMIQuery | Select-Object LocalPath
	                $WMIProfileToDrop=$TheProfileToDrop.LocalPath
	    	        Write-Output "Deleting $WMIProfileToDrop through WMI."
		            $WMIQuery.Delete()
			}
            else {
                cmd /c rd /s /q "$CurrentProfileName"
                Write-Output "No WMI-profile found, $CurrentProfileName folder was deleted though."
            }
        
    		Write-Output "$CurrentProfileName has been deleted."
		}

		else {
	    	Write-Output "$CurrentProfileName was skipped."
		}
	}
}
