Windows Server: wycinanie sesji RDP

Problem z nierozłączonymi sesjami pulpitu zdalnego może czasami prowadzić do nadmiernej utylizacji pamięci RAM lub problemów z zalogowaniem się nowych użytkowników. Poniżej przedstawiam sprawdzone sposoby na wycięcie sesji RDP.

Jak widać na powyższym zrzucie ekranu, sesje RDP o stanie „Odłączony” zabierają sporo pamięci RAM serwera terminali. Najprostszym rozwiązaniem jest edycja Lokalnych Zasad Grupy (Local Group Policy) a dokładnie polityki: Ustaw limit czasu dla sesji rozłączonych (Set time limit for disconnected sessions). Samą zasadę znajdziecie:

Konfiguracja Komputera > Szablony Administracyjne > Składniki systemu Windows > Usługi pulpitu zdalnego > Host sesji pulpitu zdalnego > Limit czasu sesji

(Computer Configuration > Administrative Templates > Windows Components > Remote Desktop Services > Remote Desktop Session Host > Session Time Limits)

To pierwszy sprawdzony sposób na ten problem.

Oczywiście różne są środowiska i różni są administratorzy. Czasami wycinanie sesji jest potrzebne na żądanie, szybko i wtedy sprawdza się wiersz poleceń oraz dwa jego polecenia. Pierwszą komendą pytamy o listę sesji:

quser

Po wykonaniu polecenia otrzymujemy listę sesji, nas będzie interesowało ID sesji którą chcemy wyciąć:

Znając ID wykonujemy następnie polecnie:

logoff 10

Oba polecenia można uzupełnić parametrem dotyczącym nazwy maszyny a z użyciem PSEXEC całość można wykonywać zdalnie. I to jest drugi sprawdzony sposób na wycinanie sesji terminalowych.

Czasami wiszące sesje chcielibyśmy wycinać masowo. Np wszystkie sesje które są rozłączone a mimo to zajmują nam zasoby. Z pomocą przychodzi nam PowerShell i dwa polecenia z modułu RemoteDesktop (moduł ten jest domyślnie instalowany na serwerze który pełni role serwera terminali). Polecenia których użyjemy to:

Get-RDUserSession

oraz komenda:

Invoke-RDUserLogoff

Całość ubrana w odpowiedni skrypt pozwoli nam wyciąć sesje wszystkich użytkowników których stan jest rozłączony.

Skrypt poniżej:

#zmienna nazwy serwera RDP dla polecenia Invoke-RDUserLogoff (parametr z nazwą serwera jest obowiązkowy)
$servername = hostname


#zmienna listy sesji RDP wybierająca tylko ID sesji użytkowników o rozłącząnym stanie,
$sessionlist = Get-RDUserSession | Where-Object {$_.Sessionstate -eq "STATE_DISCONNECTED"} | Select-Object -ExpandProperty UnifiedSessionId

#dla każdego ID ze zmiennej list sesji wykonaj komende wylogowującą użytkowniak, parametr Force opcjonalny
foreach($session in $sessionlist) {

    
     -hostserver $servername -UnifiedSessionId $session -force

}

Teraz wystarczy już tylko taki skrypt dodać do harmonogramu zadań na przykładzie naszego innego wpisu i mamy kolejny problem administracyjny z głowy.