Сброс зависших RDP сессий

    Всем у кого в хозяйстве есть терминальные сервера на Windows приходится сталкиваться с зависшими сессиями.
    Сессии частенько зависают, если пользователь просто закрыл окно терминала.
    Естественно, все мы настраиваем параметры сброса сессий по времени и отключению пользователя, но бывает что сессии все равно не завершаются и тогда мы используем команды: qwinsta — просмотр сессий и rwinsta — сброс сессий
    Абсолютно уверен что скриптик, который сам отслеживает и сбрасывет зависшие сессии, написали многие, но не выложили в сеть потому что это просто, я выложу для тех кто ищет и кому это нужно прямо сейчас:

    Скрипт получает список сессий qwinsta, выбирает сессии со статусом Диск ("*ЁбЄ*" — это тоже «Диск», просто в кривой кодировке, добавлено на всякий случай) и rwinsta сбрасывает сесии.
    В скриптике rwinsta — закомментирована, чтоб сессии сбрасывались раскомментируйте.
    В текущем виде скрипт просто покажет вам зависшие сессии.

    # Сброс зависших сессий, добавьте в расписание на своем скрипт сервере
    Function RDP_Resetfailure($server){
    	$ts = qwinsta /server:$server
    	$td = ($ts | where { ($_ -like "*Disc*" -or $_ -like "*Диск*" -or $_ -like "*ЁбЄ*" ) -and $_ -notlike "*services*"})
    	$tdselect = $td # Для отладки или внесения в лог: Login Id State
    	$td = $td -ireplace ("[^0-9]","") # оставляем только id сессий
    	for($i=0; $i -lt $td.Count; $i++){
    		Write-Host Reset RDP Failture session ID: $td[$i] $tdselect[$i]      #отладка просмотр id сессий
    		#rwinsta $td[$i] /server:$server            # сброс зависших сессий, раскомментируйте эту строку
    	}
    }
    
    $server = "MyRDPServer"
    RDP_Resetfailure($server)
    


    Добавка для тех кто предпочитает сбрасывать вручную или выборочно:
    # Для корректного отображения русской кодировки в консоли
    [Console]::outputEncoding = [System.Text.Encoding]::GetEncoding('cp866') 
    
    Function RDP_Resetfailure($server){
    	$ts = qwinsta /server:$server
    	$td = ($ts | where { ($_ -like "*Disc*" -or $_ -like "*Диск*" -or $_ -like "*ЁбЄ*" ) -and $_ -notlike "*services*"})
        $tdselect = $td # Для отладки или внесения в лог: Login Id State
    	$td = $td -ireplace ("[^0-9]","") # оставляем только id сессий
        Clear-Host
        Write-Host "
        Список зависших сессий:
        "
    	for($i=0; $i -lt $td.Count; $i++){
    		Write-Host Reset RDP Failture session ID: $td[$i] $tdselect[$i]      #отладка просмотр id сессий
    	}
    
        Write-Host
        if($td[0]){
            Write-Host "
            - Для сброса всех сесcий введите 0 
            - Или введите ID сбрасывемой сессии
            ====================================
            "
            $r = Read-Host -Prompt "Ваш выбор"
            Write-Host =============================
            # ==== Сброс всех сессий! =====
            if($r -eq 0 ){
                Write-Host
                Write-Host ==== Сброс всех сессий! =====
                for($i=0; $i -lt $td.Count; $i++){
    		        Write-Host Reset RDP Failture session ID: $td[$i] $tdselect[$i]      #отладка просмотр id сессий
    		        #rwinsta $td[$i] /server:$server            # сброс зависших сессий, раскомментируйте эту строку
                    Write-Host
    	        }
            }
    
            # Сброс сессии ID
            if($r -gt 0 ){
                $tdu = $tdselect | where { $_ -match ' '+$r  }
                Write-Host Reset RDP Failture session ID: $r $tdu
                #rwinsta $r /server:$server # сброс зависшей сессии, раскомментируйте эту строку
            }
        }
    }
    
    $server = "MyRDPServer"
    RDP_Resetfailure($server)
    

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 8

      +1
      Кодировка оригинальная, забавно.

      Добавим в копилку читателя маленький скрипт, ищущий на серверах сессии администраторов, например, чтобы простимулировать их разлогиниться и не занимать память.

      cls
      Import-Module ActiveDirectory
      $Servers = Get-ADComputer -SearchBase "OU=Servers,DC=contoso,DC=test" -Filter 'Enabled -eq $true'
      $Servers += Get-ADComputer -SearchBase "OU=Servers,OU=Moscow,DC=contoso,DC=test" -Filter 'Enabled -eq $true'
      
      $RDPArray = @()
      ForEach ($Server in $Servers) {
          $ServerName=$Server.Name
          $ping = Test-Connection $ServerName -count 1 -Quiet
          if ($ping -eq $true) {
                  $Results= qwinsta /server:$servername
                  $Results = $Results[1..$($Results.Count - 1)]
                  foreach ($Result in $Results) {
      $RDPMember = New-Object PSObject
      Add-Member -InputObject $RDPMember -MemberType NoteProperty -Name "Server" -Value $Server.Name
      Add-Member -InputObject $RDPMember -MemberType NoteProperty -Name "Session" -Value $Result.Substring(1,18).Trim()
      Add-Member -InputObject $RDPMember -MemberType NoteProperty -Name "User" -Value $Result.Substring(19,22).Trim()
      Add-Member -InputObject $RDPMember -MemberType NoteProperty -Name "ID" -Value $Result.Substring(41,7).Trim()
      Add-Member -InputObject $RDPMember -MemberType NoteProperty -Name "Status" -Value $Result.Substring(48,8).Trim()
      Add-Member -InputObject $RDPMember -MemberType NoteProperty -Name "Type" -Value $Result.Substring(56,12).Trim()
      Add-Member -InputObject $RDPMember -MemberType NoteProperty -Name "Device" -Value $Result.Substring(68,8).Trim()
      $RDPArray += $RDPMember
      		  }
          }
      }
      #$RDPArray|?{($_.User).Length -ne 0}|ft server, user, status #Показать всех пользователей
      $RDPArray|?{$_.User -like "IvanovII*" }|ft server, user, status #Найти сессии конкретного пользователя
      
        0
        Спасибо. Навели на некоторые идеи на основе вашего скрипта.
          0
          Такая кодировка в «русском» Windows PowerShell ISE.
          Помогает все отобразить в читаемом виде
          [Console]::outputEncoding = [System.Text.Encoding]::GetEncoding('cp866')
          0
          Скажите пожалуйста человеку далекому от администрирования, а это помогает от симптома «черный экран» при попытке восстановить оборанную RDP сессию? И работает ли это для не северной винды (семерки)?
            +1
            Нажми Ctrl+Alt+End и черный экран исчезнет.
              0
              спасибо
            +1
            Да это «сбрасывает» черный экран и работает на Windows начиная с версии 7 точно, включая серверные версии.
            Это не восстанавливает сессию, а сбрасывает её — выход из системы производится.
              0
              спасибо

            Only users with full accounts can post comments. Log in, please.