У меня была эта проблема с заблокированными пользователями приложения удаленного рабочего стола. Я написал этот сценарий Powershell для выполнения запланированной задачи по выходу из системы пользователей, которые были отключены более 2 минут. Единственное, что требуется отредактировать, - это имя_СЕРВЕРА, которое я установил, чтобы исключить сервер посредника удаленных рабочих столов, однако вы можете исключить любой понравившийся вам сервер или ни одного вообще.
Мой скрипт был написан для Windows Server 2012 R2, кстати ...
Сценарий делает это:
- Получает список всех сеансов пользователей удаленного рабочего стола.
- Игнорирует любые сеансы, которые не говорят "STATE_DISCONNECTED".
- Игнорирует сервер брокера (или любой другой сервер)
- Игнорирует любые сессии без единого идентификатора сессии
- Игнорирует любые сессии, которые не имеют времени отключения
- Для тех сеансов, которые имеют время отключения, он проверяет текущее время и, если разница во времени между текущим временем и временем отключения больше X минут (в данном случае 2), убивает процесс winlogon.
- Он также пытается выполнить команду выхода из системы (это, скорее всего, завершится ошибкой после завершения процесса winlogon).
Меня устраивает! Я надеюсь, что это помогает кому-то еще! :)
CLS
$RD = Get-RDUserSession | select ServerName, UserName, SessionState, DisconnectTime, UnifiedSessionId, SessionId #Get details about the sessions
foreach ($item in $RD) {
$UsessionID = $item.UnifiedSessionId -as [int]
$sessionID = $item.SessionId -as [int]
if ($item.SessionState -eq "STATE_DISCONNECTED" -and $item.ServerName -ne "SERVERNAME" -and $item.DisconnectTime -ne $null -and $item.UnifiedSessionId -ne $null){
$TimeDiff = New-TimeSpan -start $item.DisconnectTime -end (Get-Date) #check time difference between disconnect time and now. If time is greater than 2 minutes....
if ($TimeDiff.Minutes -gt 2) {
#Kill winlogon session for the user
Get-WmiObject -ComputerName $item.Servername -query "select * from win32_process where name='winlogon.exe'" | Where-Object {$_.SessionId -eq $SessionId} | %{$_.terminate()}
#Log off user if session still exists (will fail if user kicked)
Invoke-RDUserLogoff -HostServer $item.ServerName -UnifiedSessionID $UsessionID -Force -erroraction 'silentlycontinue'
}
}
}
Или, если вы предпочитаете версию, вы можете видеть, что происходит на экране:
CLS
$RD = Get-RDUserSession | select ServerName, UserName, SessionState, DisconnectTime, UnifiedSessionId, SessionId
foreach ($item in $RD) {
$UsessionID = $item.UnifiedSessionId -as [int]
$sessionID = $item.SessionId -as [int]
if ($item.SessionState -eq "STATE_DISCONNECTED" -and $item.ServerName -ne "SERVERNAME" -and $item.DisconnectTime -ne $null -and $item.UnifiedSessionId -ne $null){
#On Screen Output
write-host " Name : " $Item.UserName -ForegroundColor "yellow" -NoNewline
write-host " Unified Session Id : " $UsessionID -ForegroundColor "darkcyan" -NoNewline
write-host " User Session Id : " $sessionID -ForegroundColor "darkyellow" -NoNewline
write-host " Session State : " $item.SessionState -ForegroundColor "magenta" -NoNewline
write-host " Server : " $item.ServerName -ForegroundColor "cyan" -NoNewline
write-host " Disconnect Time : " $item.DisconnectTime -ForegroundColor "gray"
#End On Screen Output
$TimeDiff = New-TimeSpan -start $item.DisconnectTime -end (Get-Date)
if ($TimeDiff.Minutes -lt 2) {
write-host " Disconnected for less than 2 minutes" -ForegroundColor "Green"}
else {
write-host " Disconnected for more than 2 minutes" -ForegroundColor "Red" -BackgroundColor "darkyellow"
write-host " Killing session : " $item.ServerName " ID : " $UsessionID $item.UserName -ForegroundColor "Red"
#Kill Process "Winlogon.exe" for the user (this should kill the session)
Get-WmiObject -ComputerName $item.Servername -query "select * from win32_process where name='winlogon.exe'" | Where-Object {$_.SessionId -eq $SessionId} | %{$_.terminate()}
#Logout User (if session still exists)
Invoke-RDUserLogoff -HostServer $item.ServerName -UnifiedSessionID $UsessionID -Force -erroraction 'silentlycontinue'
Write-host " Done! " -ForegroundColor "Green" -BackgroundColor "blue"
}
}
}