Скрипт тихого отключения бездействующих сессий RDS
После достижения лимита простоя сессии пользователя Служб удалённых рабочих столов Remote Desktop Services (RDS) в Windows Server система выводит на экран предупреждение о истечении лимита. После чего у пользователя нет выбора, остается только нажать кнопку «ОК», что приводит к сбросу счетчика простоя. В результате сессия пользователя продолжает работать и занимать ресурсы сервера RDS. В RDS на Windows Server 2012 R2 данное сообщение всплывает на весь горизонт экрана, что приводит к стрессовым ситуациям у неподготовленных пользователей.
В качестве альтернативы штатному механизму оповещения в простаивающей сессии можно использовать PowerShell-скрипт, который будет выполнять отключение простаивающих сессий без вывода всплывающего предупреждения.
- Quietly-Disabling-Idle-RDS-sessions.ps1
#Путь к списку серверов RDS в формате txt $path_list_srv = "c:\mylistservers.txt" #Установка лимита простоя в минутах $Idle_minutes = 30 #Загрузка списка серверов $Servers = $Null $Servers = Get-Content -Path $path_list_srv #Если список серверов пуст то выход if ($Servers -eq $Null) {exit} foreach($Srv in $Servers){ #Получаем данные с сервера RDS о сессиях $List_i = $Null $List_i = quser /server:$Srv #Обработка данных сессий foreach ($i in $List_i){ Get-Variable -Name "u_*" | Clear-Variable $u_array = $i -split " " | ? {$_} $u_login = $u_array[0] $u_session = $u_array[1] $u_Idle_t = $u_array[$u_array.count-3] #Преобразование idle time в временной формат if ($u_Idle_t -ne $Null){ $u_Idle_t = $u_Idle_t -replace "\+",":" -replace "\.","0:0" -replace "Disc","0:0" if($u_Idle_t -like "*:*"){ $u_Idle_t = [timespan]"$($u_Idle_t)" }elseif($u_Idle_t -eq "." -or $u_Idle_t -eq "none"){ $u_Idle_t = [timespan]"0:0" }else{ $u_Idle_t = [timespan]"0:$($u_Idle_t)" } #Редко RDS выдает неверное idle time для активной сессии, оно превышает 1000 дней if ( [int]$u_Idle_t.Days -gt 1000){$u_Idle_t = New-TimeSpan} } #Если idle time превышает заданный интервал то сессия отключается if ([int]$u_Idle_t.TotalMinutes -ge $Idle_minutes){ write-host -ForegroundColor yellow $Srv : $u_login / $u_Idle_t.TotalMinutes tsdiscon /SERVER:$Srv $u_session }ELSE{write-host -ForegroundColor green $Srv : $u_login / $u_Idle_t.TotalMinutes} } }
Для работы скрипта необходимы права локального администратора на обрабатываемых серверах RDS.
Проверено на следующих конфигурациях:
Версия ОС | Версия служб RDS | Версия Powershell |
---|---|---|
Windows Server 2012 R2 Standard (6.3.9600) | RDS 5.1 | PowerShell 4.0 |
Автор первичной редакции:
Дмитрий Исупов
Время публикации: 05.09.2018 10:00
Обсуждение
а так же вылазит сообщение об шибки преобразования:
Cannot convert value "040:0020:02020" to type "System.TimeSpan". Error: "The TimeSpan could not be parsed because at least one of the numeric components is out of range or contains too many digits."
At C:\Scripts\LogOff\logoff4.ps1:29 char:31
+ $u_Idle_t = [timespan]"$($u_Idle_t)"
+ ~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvalidCastParseTargetInvocationWithFormatProvider
Скрипт применим также для персональных компьютеров под управлением ОС Windwos XP - 10,
но хотелось бы уточнить важную деталь, скрипт отключает сеанс.
Иными словами произойдет блокировка, а не выход.
Если вам требуется завершение консольной сессии используйте
shutdown -f /m ('\\' + $Srv)
вместо
tsdiscon /SERVER:$Srv $u_session
По ошибке
quser возвращает непредвиденные данные.
Пришлите ответ команды "quser /server:[Имя машины]" для анализа.
ПОЛЬЗОВАТЕЛЬ СЕАНС ID СТАТУС БЕЗДЕЙСТВ. ВРЕМЯ ВХОДА
user1 console 5 Активно 23:49 04.02.2020 14:38
testgpo2 6 Диск 23:49 04.02.2020 17:02
$u_login = ($i -split " " | ?{$_})[0]
$u_session = ($i -split " " | ?{$_})[1]
$u_Idle_t = ($i -split " " | ?{$_})[4]
На
$u_array = $i -split " " | ? {$_}
$u_login = $u_array[0]
$u_session = $u_array[1]
$u_Idle_t = $u_array[$u_array.count-3]
https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/logoff
а как сделать исключения на некоторых пользователей, чтобы их даже при превышении тайминга не отключало или не срабатывала функция logoff ?
Для начала нужен массив логинов для исключения.
[array]$excep_login_list
Из файла массив загрузить можно так : $excep_login_list = Get-Content -Path [путь к файлу]
Сразу после строк доп. обработки сессии
#Редко RDS выдает неверное idle time для активной сессии, оно превышает 1000 дней
if ( [int]$u_Idle_t.Days -gt 1000){$u_Idle_t = New-TimeSpan}
Добавим обработку исключений, исключив их таким же методом.
if ( ($excep_login_list | Where-Object {$_ -eq $u_login}) -ne $NUll){$u_Idle_t = New-TimeSpan}
Не удается преобразовать значение "0:TIME" в тип "System.TimeSpan". Ошибка: "Строка не распознана как де
йствительный TimeSpan."
C:\ps\Quietly-Disabling-Idle-RDS-sessions.ps1:36 знак:33
+ $u_Idle_t = [timespan]"0:$($u_Idle_t)"
+ ~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvalidCastParseTargetInvocationWithFormatProvider
Что я делаю не так?
П.С. скрип у меня работает из файла .PS1