PowerShell · 25.04.2022

Logoff всех RDP сессий

Методов инициировать выход для пользователя в рамках сервера удалённых рабочих столов — целая уйма. Здесь и обращения к утилитам qwinsta и quser, и дополнительные пакеты для PowerShell, и куча дополнительных программ. Вот только все эти методы построены на одном принципе — получить ID сессии и вызвать для нее logoff.exe. Всё достаточно прозаично и не стоит того, чтобы строить очередной замок из песка… Метод выхода, по своей сути, прост и должен быть универсален, работать в любых условиях.

Получать ID RDP сессии напрямую через quser предполагает парсинг выдачи. С этим я сталкивался, когда писал вот этот скрипт. Процесс не быстрый и не очень надёжный, как любая выборка данных из командной строки.

Куда проще обстоят дела с получением идентификатора сессии пользователя, если использовать ответы от PowerShell. За константу я взял тот факт, что у каждого пользователя запущен Проводник Windows (explorer.exe) и именно это и стало точкой отсчёта. Остаётся только получить ID всех пользовательских сессий, где запущен explorer.exe. Конечный скрипт выглядит вот так:

## Шапка скрипта ##
[System.Console]::Title = "Завершение сессий пользователей"
Write-Host "Запущен процесс выхода пользователей..." -ForegroundColor Red

## Отправка команды LOGOFF в цикле ##
Invoke-Command -ComputerName RDS01, RDS02, RDS03 -ScriptBlock { 
    $explorer = Get-WMIObject win32_process | where {$_.ProcessName -eq "explorer.exe"}
    foreach ($exe in $explorer) { logoff $exe.SessionID }
}

## Ожидание действий от пользователя ##
Write-Host "Процесс выхода пользователей завершён!" -ForegroundColor Cyan
Read-Host "Нажмите Enter для выхода..."

Отдельную переменную для списка серверов объявлять не стал. Всё, что нужно — это поменять имена серверов в атрибуте «-ComputerName«.