Невозможно выйти из системы, отключить или сбросить пользователя сервера терминалов в производственной среде


19

Я ищу некоторые идеи о том, как отключить, выйти из системы или сбросить сеанс пользователя на сервере терминалов 2008 (невозможно войти в систему как пользователь, так как он полностью заблокирован). Это производственная среда, поэтому о перезагрузке сервера или выполнении общесистемных операций пока не может быть и речи. Какие-нибудь хитрости Powershell, чтобы помочь нам с этим?

Мы попытались отключить, отключить пользователя и сбросить сеанс, а также убить процессы сеанса также напрямую с одного и того же сервера терминалов (из диспетчера задач, диспетчера служб терминалов и монитора ресурсов) без результатов.

Помогите!


ОБНОВЛЕНИЕ: Мы закончили тем, что перезагрузили сервер, поскольку никакие другие попытки, о которых мы могли думать, не работали. Я оставлю этот вопрос открытым, надеясь, что у кого-то будет больше информации об этой проблеме, и это потенциальные исправления


2
У меня точно такая же проблема на моих терминальных серверах Windows 2008 R2 SP1. Они просто случайно зависают, и пользователи не могут выйти или войти на сервер. Я не могу войти в систему как локальный администратор или администратор домена. Единственный способ подключиться к серверу - использовать compmgmt.msc, но даже здесь я не вижу проблем в журналах событий. На каком-то этапе я получаю сообщение о том, что служба IMA не отвечает, и сервер был удален из фермы. Единственный способ решить эту проблему - перезагрузить сервер Hard. Выключите и снова включите. Я не смог сузить причину этого до чего-либо, и я



1
Потенциально полезные ссылки для любого, кто сталкивается с этой проблемой, идет вперед
JohnLBevan

Ответы:


7

Для решения этой же проблемы мне удалось убить все процессы, запущенные под заблокированной учетной записью, из-под диспетчера задач, а затем я смог просто выйти из этой учетной записи (из учетной записи администратора).

Затем пользователь смог снова войти в систему под учетной записью.

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


-Спасибо, спас меня от перезагрузки сервера! Действительно не хотел выгнать всех в течение рабочего дня из-за 1 застрявшей сессии.
MAW74656

Безопасно ли убивать эти процессы? Мой пользователь имеет csrss.exe, dwm.exe, LoginUI.exeи winlogon.exe. Я думал, что убийство winlogon.exeвызовет BSOD ...
Бинки

6

Я хочу поделиться тем, как я сбрасываю учетную запись без необходимости перезагрузки сервера. Прежде всего вам необходимо иметь доступ администратора к серверу. Я использую следующую опцию входа в систему: mstsc / v: имя_сервера / console / admin для доступа к серверу. Затем в «Менеджере Windows Taks» перейдите на вкладку « Пользователи » и выполните правый клик по учетной записи, для которой вы хотите «Выйти», выберите «Выйти из системы». Это должно освободить заблокированный сеанс, используемый этой учетной записью.


1
кроме этого не всегда. Плюс ОП сказал, что они уже попробовали это.
BeowulfNode42

Для этой проблемы кнопка «Выход» в диспетчере задач → Пользователи ничего не делает.
Бинки,

5

Простой ответ - запустить командную строку с повышенными привилегиями и ввести «Taskmgr», после чего вы сможете выйти из сеансов на вкладке USERS. Это не будет работать без участия в повышенном сеансе.


Проверено и это решение сработало.
Сверхразум

1
Не для меня. Также не может использовать TaskManager в качестве администратора, чтобы убить любой из процессов пользователя либо.
BeowulfNode42

3

Вы можете запустить cmd, выполнить сеанс запроса , проверить идентификатор сеанса, который нужно уничтожить, а затем выполнить сеанс сброса . Например, если с сеансом запроса вы получаете, что имя сеанса rdp-tcp # 1 является тем, которое вы хотите убить, тогда вы можете выполнить сброс сеанса rdp-tcp # 1 и убить его.


Спасибо, но это тоже не помогло.
l0c0b0x

Когда я запускаю reset session 9эту команду просто зависает. Моя сессия продолжает иметь четыре запущенные процессы , не представляясь быть активным: crss.exe, dwm.exe, LogonUI.exe, и winlogon.exe. i.imgur.com/cFM62RA.png и query session 9результаты No User exists for 9.
Бинки

3

Я полагаю, то же самое произошло сегодня на моем терминальном сервере Win2008R2. Симптомы были: 1. Он позвонил мне с сообщением «Соединение просто висит навсегда». Он простой пользователь, поэтому я не могу ожидать подробного описания проблемы. 2. Пробовал выходить из системы / сбрасывать сеанс (что обычно помогает в этих случаях) - не сработало. Сессия все еще висит в списке со статусом «отключено». 3. Пробовал убивать все процессы для этого пользователя - не помогло. Сессия продолжается и отказывается быть убитой.

Решение было - подключиться как пользователь (войдите с его учетными данными, если вы можете сбросить его пароль или использовать какую-то удаленную помощь, чтобы увидеть, что происходит на его компьютере) и посмотреть, что происходит в окне входа. При подключении я нажал на кнопку «Подробности» клиента RDP - и вот оно, было сообщение об ошибке, что winlogon сделал что-то не так, он ждал, когда пользователь нажмет на кнопки «повторить / игнорировать / и т. Д.», И так как это был всемогущий winlogon, он вызвал все это странное поведение.

PS Я не мог найти способ действительно заставить убить сеанс :(


Это исправило это для меня! Он ждал, пока пользователь выберет отключить другого пользователя или нажать «Отмена». Я нажал «Отмена», и теперь тот пользователь, который застрял на вкладке «Пользователи» в диспетчере задач, исчез. Благодарность!
Бинки,

Вот как выглядела моя ситуация, когда возникла такая проблема: i.imgur.com/W6eO5wW.png i.imgur.com/EpPwyJc.png i.imgur.com/cFM62RA.png Кроме того, я использую Windows Server 2016
Бинки

3

У нас только что была похожая проблема с нашим сервером удаленного рабочего стола Windows Server 2008 R2. Сеанс пользователя показывал «Активно» при просмотре RDS Manager, но у него не было идентификатора ассоциированного сеанса или показа подключенного устройства (оба были пустыми).

Все вышеперечисленные трюки не решили проблему. При подключении в качестве пользователя, о котором идет речь, возвращалось сообщение об ошибке, в котором говорилось, что сервер терминалов был занят и повторите попытку позже или обратитесь к администратору.

Мы также перезагрузили сервер.


2

У меня была такая же проблема в Windows Server 2016. Пользователь не смог войти в систему.

Поэтому я попытался выполнить следующие шаги, чтобы отключить потерянный сеанс:

  1. в CLI qwinsta перечисляет все доступные сеансы, неактивные и активные, есть один отключенный сеанс (называемый «getr.» на скриншоте) без имени пользователя, но с идентификатором сеанса.

показывать активные сессии и убивать их

  1. с идентификатором сеанса (7) из 1. Я пытался убить этот сеанс с помощью любого сеанса сброса 7 (fyi: rwinsta - псевдоним для сеанса сброса)

  2. это работало в течение одного сеанса, но в следующий раз это не имело никакого эффекта, поэтому я открыл диспетчер задач и вкладку пользователя. Там вы найдете один расширяемый список, назначенный каждому пользователю удаленного рабочего стола - один список не имеет имени пользователя и показывает только 4 запущенных задачи.

  3. Я попробовал очевидное: выход пользователя из системы. Без какого-либо эффекта.

пытаясь выйти из системы пользователя

  1. Поэтому я попытался завершить эти 4 задачи, назначенные этому пользователю. Будьте осторожны, потому что некоторые задачи, наиболее важные из которых - csrss.exe, после их закрытия также могут привести к перезагрузке системы. Я пропустил их и просто убил несколько очевидных RDP-задач.

После шага / попытки 4 даже последний сбойный сеанс был уничтожен, и пользователь смог снова войти в систему

  1. Если это все еще не работает, попробуйте это решение из другого вопроса : Когда вы подключаетесь к клиенту RDP, нажмите кнопку «Детали». Там вы должны увидеть ошибку, и вы можете даже нажать кнопку повтора или игнорировать .

Можете ли вы более конкретно указать, какие процессы вы убили, а какие нет? Я думаю , что я должен пропустить , winlogon.exeно не уверен , о других , как LoginUI.exe, csrss.exe, и dwm.exe.
Бинки

Симптомы для второго сеанса у вас были похожи на мои и serverfault.com/a/176080/164429 . Возможно, вы могли бы добавить «Connect» в качестве шага, чтобы попытаться найти более полное решение и, возможно, даже избежать необходимости убивать процессы.
Бинки,

@binki должно быть «csrss.exe» - если вы убьете этот процесс, система перезагрузится.
Н.Р.

1

Возможно, стоит проверить, что у пользователя нет всплывающего окна с учетными данными, скрытого за окном удаленного рабочего стола с помощью alt + tab.

У коллеги возникла та же проблема; не удалось выйти из системы или выполнить сброс, и все его процессы были закрыты вручную. Когда я попытался получить доступ к графическому интерфейсу системы, с которой он удаленно работал, я обнаружил поле для учетных данных, скрытое за удаленным сеансом.


1

Я бы поступил точно так же: Windows Server 2008 R2 со службами удаленных рабочих столов, RDP-соединение, настроенное для выхода из системы пользователей после того, как сеанс неактивен или отключен через 3 часа, а некоторые сеансы все еще остаются заблокированными. Я попытался выйти из системы с помощью Remote Desktop Manager и qwinsta / quser, но безуспешно.

Вот как я решил это:

  1. Я нашел идентификатор сессии с qwinsta.
  2. Я нашел PID winlogon.exeдля зависшей сессии query process /ID:yourid.
  3. Я убил процесс с taskkill /f /PID yourPID.

Путь В противном случае я бы хотел найти решение, чтобы этого не произошло.


1

Что сработало для меня:

  • войти на сервер
  • открыть диспетчер задач
  • искать пользователя во вкладке пользователя
  • щелкните правой кнопкой мыши, подключитесь, введите пароль пользователя, я увидел экран «Пожалуйста, подождите»
  • нажмите alt-tab, чтобы выйти из системы с сервера и выйти из системы

1

У меня была эта проблема с заблокированными пользователями приложения удаленного рабочего стола. Я написал этот сценарий 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"
                }
             }
          }

1

Создайте файл в блокноте и назовите его findsession.cmd. Поместите команду Query Session / server: имя_сервера | найти / i "% 1" и сохранить в каталог. Создайте другой файл с именем resetsession.cmd, поместите команду «Сбросить сеанс% 1 / сервер:% 2» и сохраните.

В командной строке перейдите в каталог, в котором вы сохранили эти файлы, и введите findsession username (логин пользователя, которого вы пытаетесь найти). Нажмите Enter, и вы должны увидеть логин и идентификатор сессии. Введите resetsession.cmd ID Servername, и он сбросит этот сеанс. Я использую это ежедневно, и это очень быстро для поиска пользователей и сброса их сессий.


Пожалуйста, используйте параметры форматирования текста, чтобы выделить команды и повысить удобочитаемость. Это хороший ответ, но, пожалуйста, отредактируйте его.
Марко

Нет смысла писать командные файлы, когда команды такие короткие, и вам все равно придется передавать им аргументы
binki

1
  1. Найдите идентификатор сеанса с помощью qwinsta.
  2. Убейте все процессы в сеансе taskkill /FI "SESSION eq 1" /F, предполагая, что ID сеанса, который вы хотите завершить, возвращен из qwinsta, равным 1.

Это работало на Server 2012 версии 6.2 Build 9200, я ожидаю, что он будет работать на всех версиях Windows.


1

Этот скрипт Power-Shell работал для меня, он даже дает хороший файл журнала. Я получил это отсюда. Я надеюсь, что это поможет кому-то еще, так как другие ответы имели много предпосылок и не работали для меня.

    # .SYNOPSIS
    #   Checks for disconnected sessions and logs off the disconnected user sessions.

    #.DESCRIPTION
    #   Checks for disconnected sessions and logs off the disconnected user sessions.

    #.NOTES
    #   File Name: Logoff-DisconnectedSession.ps1
    #   Author   : Bart Kuppens
    #   Version  : 1.1

    #.EXAMPLE
    #   PS > .\Logoff-DisconnectedSession.ps1


    function Ensure-LogFilePath([string]$LogFilePath)
    {
     if (!(Test-Path -Path $LogFilePath)) {New-Item $LogFilePath -ItemType directory >> $null}
    }

    function Write-Log([string]$message)
    {
       Out-File -InputObject $message -FilePath $LogFile -Append
    }

    function Get-Sessions
    {
       $queryResults = query session
       $starters = New-Object psobject -Property @{"SessionName" = 0; "UserName" = 0; "ID" = 0; "State" = 0; "Type" = 0; "Device" = 0;}
       foreach ($result in $queryResults)
       {
          try
          {
             if($result.trim().substring(0, $result.trim().indexof(" ")) -eq "SESSIONNAME")
             {
                $starters.UserName = $result.indexof("USERNAME");
                $starters.ID = $result.indexof("ID");
                $starters.State = $result.indexof("STATE");
                $starters.Type = $result.indexof("TYPE");
                $starters.Device = $result.indexof("DEVICE");
                continue;
             }

             New-Object psobject -Property @{
                "SessionName" = $result.trim().substring(0, $result.trim().indexof(" ")).trim(">");
                "Username" = $result.Substring($starters.Username, $result.IndexOf(" ", $starters.Username) - $starters.Username);
                "ID" = $result.Substring($result.IndexOf(" ", $starters.Username), $starters.ID - $result.IndexOf(" ", $starters.Username) + 2).trim();
                "State" = $result.Substring($starters.State, $result.IndexOf(" ", $starters.State)-$starters.State).trim();
                "Type" = $result.Substring($starters.Type, $starters.Device - $starters.Type).trim();
                "Device" = $result.Substring($starters.Device).trim()
             }
          } 
          catch 
          {
             $e = $_;
             Write-Log "ERROR: " + $e.PSMessageDetails
          }
       }
    }

    Ensure-LogFilePath($ENV:LOCALAPPDATA + "\DisconnectedSessions")
    $LogFile = $ENV:LOCALAPPDATA + "\DisconnectedSessions\" + "sessions_" + $([DateTime]::Now.ToString('yyyyMMdd')) + ".log"

    [string]$IncludeStates = '^(Disc)$'
    Write-Log -Message "Disconnected Sessions CleanUp"
    Write-Log -Message "============================="
    $DisconnectedSessions = Get-Sessions | ? {$_.State -match $IncludeStates -and $_.UserName -ne ""} | Select ID, UserName
    Write-Log -Message "Logged off sessions"
    Write-Log -Message "-------------------"
    foreach ($session in $DisconnectedSessions)
    {
       logoff $session.ID
       Write-Log -Message $session.Username
    }
    Write-Log -Message " "
    Write-Log -Message "Finished"  

Редактировать:
я изначально использовал этот скрипт для выхода из системы и закрытия всех «отключенных» сессий. У нас есть пара приложений терминального сервера со многими пользователями и ограниченными лицензиями. Отключенные сеансы оставались открытыми в течение очень долгого времени, а иногда они оставались открытыми неограниченное время. Это привело к неиспользуемым сеансам, которые занимали бы некоторые лицензии, и в результате другие пользователи не могли бы подключиться в результате.

  • Я запускаю скрипт, используя запланированное задание, чтобы регулярно проверять и
    отключать сеансы на некоторых из моих серверов. Он работает автономно
    без какого-либо взаимодействия.
  • Я использую его в операционных системах Windows 2008 R2 Server и Windows 2012 R2 Server.
  • Он закрывает только сеансы, которые были отключены.
  • Он обновляет файл журнала с пользователями или сеансами, которые он отключил.

Не могли бы вы объяснить, что он делает?
Конрад Гаевский

1
Привет, Конрад, я немного отредактировал ответ и надеюсь, что он объяснит, что делает сценарий. По сути, скрипт закрывает все отключенные сеансы, которые остаются открытыми после отключения удаленного пользователя от сервера.
9953-div-37

0

Возможно, процесс все еще работает, блокируя процесс выхода из системы. Проверьте все еще запущенные процессы для затронутого пользователя. Затем убейте процесс один за другим, чтобы увидеть, кто вызывает эту проблему.

Проверьте также HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Runключ реестра, в котором запускаются только необходимые процессы. В 64bit это так HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run.


0

Вы можете скачать инструмент « Process Explorer » от Microsoft и использовать его для решения вашей проблемы. Если у вас есть идентификаторы сеансов, вы можете найти их соответствующие процессы. Затем, если пользовательский сеанс отключен, вы можете завершить процесс с помощью Process Explorer.


0

Не совсем та же среда (у нас 2012r2), но перезапуск службы управления виртуальными машинами Hyper-V (VMMS) освободил мне соединение.


0

Вам нужно нажать на процесс и показать процесс от всех пользователей, и тогда вы сможете отключиться.

почему бы не создать политику сеанса в разделе Конфигурация хоста сеанса удаленного рабочего стола в конце отключен или неактивен после определенного интервала.


0

Мое исправление: на другом сетевом сервере я подключился к проблемному серверу с помощью инструмента «Управление компьютером», в открытых сеансах я щелкал правой кнопкой мыши и закрывал каждый открытый файл, после чего смог подключиться через mstsc


0

вы всегда можете использовать powershell с вашей локальной машины и делать это удаленно

Invoke-command -computername <servername> -Credential (get-credential) { 
    $session = ((quser | ? { $_ -match <username> }) -split ' +' )[2]
    logoff $session
} 

Чтобы сделать ваш ответ еще более полезным, было бы полезно дать базовое объяснение того, как работает эта команда. Не каждый может быть достаточно опытным с PowerShell, чтобы понять это. Спасибо за помощь.
Я говорю Восстановить Монику

-1

К сожалению. Мой пользовательский сеанс был отключен. Диспетчер задач не показал никаких процессов, запущенных от имени пользователя. Я не мог выйти из системы из диспетчера задач. Я попытался сбросить команду идентификатора сеанса и закончил тем, что зависал также. Мне пришлось в конечном итоге войти в другой сеанс с правами администратора, удалить учетную запись и заново создать новую.


-1

Вы пытались выйти из системы из диспетчера служб удаленных рабочих столов? Перейдите в Администрирование -> Службы удаленных рабочих столов -> Диспетчер служб удаленных рабочих столов и выйдите из сеанса. Это может сработать.


-1

Перейти в стартовое окно и нажмите на свое имя

Смотрите образец здесь


Я думаю, что это повтор некоторых других ответов здесь (большинство из которых довольно подробны) - например, serverfault.com/a/804638/402709 . Это может помочь улучшить ваш ответ, чтобы расширить его с некоторым контекстом и вашим собственным опытом.
iwaseatenbyagrue

Я так не думаю, но наслаждаюсь этим.
Syb
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.