Skip to content

Instantly share code, notes, and snippets.

@figueroadavid
Last active May 18, 2023 20:04
Show Gist options
  • Select an option

  • Save figueroadavid/4703f0bc076073cbda0cb764aa98bcf5 to your computer and use it in GitHub Desktop.

Select an option

Save figueroadavid/4703f0bc076073cbda0cb764aa98bcf5 to your computer and use it in GitHub Desktop.
Newest version, Citrix only, but removes all the hung sessions in the farm without attached users and in an 'Application Not Running' state
#Requires -Module Citrix.Broker.Admin.V2
function Remove-BadWinLogonSession {
<#
.DESCRIPTION
This function searches for sessions that are in a NoApps state (Applications Not Running) and
also do not have a BrokeringUserName. This state indicates a session with a hung winlogon.exe
process that is not "owned" by anyone. Sessions in a NoApps state, but have a BrokeringUserName
are valid inactive sessions and are not modified.
.SYNOPSIS
This function removes winlogon processes for dead sessions.
.PARAMETER ControllerName
This is the Citrix Delivery Controller to access for this process.
.NOTES
The script uses CIM and accesses both the Citrix and CIMV2 namespaces.
.EXAMPLE
PS C:\> Remove-BadWinlogonSession -ControllerName CTXDDC01 -Verbose
VERBOSE: This session (87) is a DEAD session; the processID is (45208); stopping this process
VERBOSE: This session (78) is a LIVE session; the processID is (6664)
VERBOSE: This session (94) is a LIVE session; the processID is (47824)
VERBOSE: This session (106) is a LIVE session; the processID is (24296)
VERBOSE: This session (78) is a DEAD session; the processID is (49184); stopping this process
VERBOSE: This session (63) is a LIVE session; the processID is (46596)
VERBOSE: This session (87) is a LIVE session; the processID is (37556)
VERBOSE: This session (57) is a DEAD session; the processID is (16108); stopping this process
VERBOSE: This session (96) is a DEAD session; the processID is (45984); stopping this process
VERBOSE: This session (87) is a DEAD session; the processID is (42556); stopping this process
VERBOSE: This session (104) is a DEAD session; the processID is (28000); stopping this process
VERBOSE: This session (40) is a LIVE session; the processID is (34572)
.INPUTS
[string]
.OUTPUTS
None
#>
[cmdletbinding()]
param(
[parameter(ValueFromPipelineByPropertyName, Mandatory)]
[string]$ControllerName
)
$DeadSessionParams = @{
AdminAddress = $ControllerName
AppState = 'NoApps'
BrokeringUserName = $null
}
$DeadSessionHosts = Get-BrokerSession @DeadSessionParams |
Where-Object { $null -eq $_.BrokeringUserName } |
Select-Object -ExpandProperty HostedMachineName
foreach ($thisHost in $DeadSessionHosts) {
Write-Verbose -Message ('Processing ({0})' -f $thisHost)
$CitrixSessionSplat = @{
ComputerName = $thisHost
NameSpace = 'Root\Citrix\hdx'
ClassName = 'Citrix_Sessions'
}
$CitrixSessionIDList = (Get-CimInstance @CitrixSessionSplat).SessionID
$WinLogonSplat = @{
ComputerName = $thisHost
ClassName = 'Win32_Process'
Filter = "Caption = 'winlogon.exe' AND SessionID > 1"
}
$WinLogonList = Get-CimInstance @WinLogonSplat
foreach ($SessionID in $WinLogonList.SessionID) {
$thisSession = $WinLogonList | Where-Object SessionID -eq $SessionID
if ($CitrixSessionIDList -Contains $SessionID) {
$Message = 'This session ({0}) is a LIVE session on {1}' -f $thisSession.SessionId, $thisHost
}
else {
$Message = 'This session ({0}) is a DEAD session on {1}; the processID for winlogon.exe is ({2}); stopping this process' -f $thisSession.SessionId, $thisHost, $thisSession.ProcessId
$thisSession | Remove-CimInstance
}
Write-Verbose -Message $Message
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment