在生产环境中无法注销,断开连接或重置终端服务器用户


19

我正在寻找有关如何在2008终端服务器中断开,注销或重置用户会话的一些想法(由于完全锁定,因此无法以用户身份登录)。这是一个生产环境,因此目前不建议重新启动服务器或在系统范围内执行任何操作。有任何Powershell技巧来帮助我们吗?

我们试图直接从同一终端服务器(从任务管理器,终端服务管理器和资源监视器)断开连接,注销用户并重置会话以及终止会话进程,但没有结果。

救命!


更新:我们最终重启了服务器,没有其他我们认为可以做的尝试有效。我将保留这个问题,希望有人可能对此问题有更多信息,并且有潜在的解决方法


2
我的Windows 2008 R2 SP1终端服务器上出现完全相同的问题。它们只是随机挂起,用户无法注销或登录服务器。我无法以本地管理员或域管理员身份登录本地。连接到服务器的唯一方法是使用compmgmt.msc,但即使在这里,我也无法在事件日志中看到任何问题。在某个阶段,我会收到一条消息,指出IMA服务没有响应,并且服务器已从服务器场中删除。解决此问题的唯一方法是重新启动服务器Hard。关闭电源,然后再次打开。我无法将其原因缩小到任何原因,我



1
对于任何遇到此问题的人都可能有用的链接
JohnLBevan 2014年

Answers:


7

解决该问题的方法是从“任务管理器”中杀死在锁定帐户下运行的所有进程,然后我可以从管理员帐户简单注销该帐户。

然后,用户便可以使用该帐户重新登录。

无需重新启动,也无需下载第三方软件。


-谢谢,让我免于重启服务器!真的不想在工作日中将所有人赶出场,因为1次会议陷入僵局。
MAW74656

杀死这些进程是否安全?我的用户有csrss.exedwm.exeLoginUI.exe,和winlogon.exe。我以为杀害winlogon.exe会引发蓝屏
死刑

6

我想分享无需重启服务器即可重置帐户的方式。首先,您需要具有对服务器的管理员访问权限。我使用以下登录选项:mstsc / v:服务器名 / console / admin,以便访问服务器。然后在“ Windows Taks Manager”中,转到“ 用户”选项卡,然后在要“注销”的帐户上单击鼠标右键,然后选择“注销”。这应该释放该帐户使用的锁定的会话。


1
除了并非总是如此。另外,OP说他们已经尝试过了。
BeowulfNode42 '18

对于此问题,任务管理器→用户中的“退出”按钮不起作用。
宾基

5

简单的答案是运行提升权限的命令提示符并键入“ Taskmgr”,然后它将允许您注销“用户”选项卡下的会话。如果不参加高级会议,它将无法正常工作。


经过测试,该解决方案有效。
主宰

1
不适合我。也不能使用taskmanager作为管理员来杀死用户的任何进程。
BeowulfNode42 '18

3

您可以启动cmd,执行查询会话,检查要杀死的会话的ID,然后执行重置会话。例如,如果通过查询会话获得会话名称rdp-tcp#1是您要终止的名称,则可以执行重置会话rdp-tcp#1并使其终止。


谢谢,但这也没有帮助。
l0c0b0x 2010年

当我运行reset session 9该命令时,它将挂起。我会继续在运行没有出现被激活的四个过程:crss.exedwm.exeLogonUI.exe,和winlogon.exei.imgur.com/cFM62RA.pngquery session 9输出No User exists for 9
宾基

3

我想今天在Win2008R2终端服务器上也发生了同样的情况。症状是:1.他给我打了“正在连接的消息,直到永远挂死”的电话。他只是一个简单的用户,所以我不能期望详细的问题描述。2.尝试注销/重置会话(在这些情况下通常会有所帮助)-无效。会话仍挂在状态为“已断开”的列表中。3.尝试杀死该用户的所有进程-没有帮助。会话持续进行,并拒绝被杀死。

解决方案是-以用户身份连接(如果可以重置其密码或使用某种远程协助以查看其计算机上的情况,请使用其凭据登录)并在登录窗口中查看情况。连接时,我单击了RDP Client的“详细信息”按钮-这是一条错误消息,指出winlogon做错了一些事情,它在等待用户单击“重试/忽略/等”按钮,并且由于它是无所不能的winlogon,所有这些奇怪的行为。

附言:我找不到任何真正强制杀死会话的方法:(


这为我解决了!它正在等待用户选择断开其他用户的连接或单击取消。我点击了取消,现在卡在任务管理器“用户”选项卡中的用户消失了。谢谢!
宾基

这就是问题所在 时的情况:i.imgur.com/W6eO5wW.png i.imgur.com/EpPwyJc.png i.imgur.com/cFM62RA.png另外,我正在使用Windows Server 2016
binki

3

我们的Windows Server 2008 R2远程桌面服务器刚刚遇到了类似的问题。当查看RDS Manager时,用户会话显示为“活动”,但未显示关联的会话ID#或连接的设备(均为空白)。

上面的所有技巧都无法解决问题。当以有问题的用户身份连接时,返回一条错误消息,指出终端服务器正忙,请稍后再试或联系管理员。

我们还完成了重新启动服务器的工作。


2

Windows Server 2016中存在相同的问题。用户无法登录。

因此,我尝试了以下步骤来断开孤立的会话:

  1. 在CLI qwinsta上列出了所有可用的会话,无论是非活动会话还是活动会话,都有一个断开连接的会话(在屏幕快照中称为“ getr。”),没有用户名,而是一个会话ID。

显示活动会话并杀死它们

  1. 会话ID为(7)从1开始。我试图用任一重置会话7 终止该会话(仅供参考:rwinsta是重置会话的别名)

  2. 它只能在一个会话中使用,但是下次它没有任何作用,因此我打开了任务管理器和“用户”选项卡。在这里,您可以找到一个分配给每个远程桌面用户的可扩展列表-一个列表中没有用户名,仅显示4个正在运行的任务。

  3. 我尝试了一个显而易见的方法:注销用户。没有任何效果。

尝试注销用户

  1. 因此,我试图结束分配给该用户的这4个任务。请小心,因为某些任务(最重要的是csrss.exe)被杀死时,也将导致系统重新启动。我跳过了它们,只是杀死了一些明显的RDP任务。

在第4步/尝试4之后,即使最后一个崩溃的会话也被杀死,并且用户能够再次登录

  1. 如果仍然不能解决问题,请尝试另一个问题尝试以下解决方案:与RDP客户端连接时,单击其“详细信息”按钮。在那里,您应该会看到一个错误,甚至可以单击重试忽略

您能否更具体地说明您杀死了哪些进程以及哪些进程没有被杀死?我想,我应该跳过winlogon.exe,但我不确定其他人一样LoginUI.execsrss.exedwm.exe
宾基

您第二次会话的症状听起来与mine和serverfault.com/a/176080/164429相似。您可能会添加“连接”作为尝试更完整的解决方案的步骤,甚至可能避免取消进程。
宾基

@binki应该是“ csrss.exe”-如果您终止了此过程,系统将重新启动。
NR

1

可能值得检查的是,用户没有在带有alt +选项卡的远程桌面窗口后面隐藏凭据弹出框。

一个同事有同样的问题。无法注销或重置,并且他的所有进程都被手动关闭。当我尝试访问他要从其远程处理的系统的gui时,我发现了隐藏在远程会话后面的凭据框。


1

我处于相同的情况:具有远程桌面服务的Windows Server 2008 R2,RDP连接设置为在会话处于非活动状态或断开连接3小时后仍注销用户,并且某些会话仍保持锁定状态。我尝试使用远程桌面管理器和qwinsta / quser注销它们,但均未成功。

这是我的解决方法:

  1. 我已经找到了会话ID qwinsta
  2. 我已经找到winlogon.exe了挂起会话的PIDquery process /ID:yourid
  3. 我已经用杀死了这个过程taskkill /f /PID yourPID

要走的路。我想以其他方式找到解决方案,以防止这种情况发生。


1

对我有用的是:

  • 登录服务器
  • 打开任务管理器
  • 在用户标签中寻找用户
  • 右键单击,连接,输入用户密码,我看到了“请稍候”屏幕
  • 按alt-tab键,该操作将我从服务器注销并也注销了用户

1

锁定的远程桌面应用程序用户遇到了这个问题。我编写了此Powershell脚本以执行计划任务,以注销显示为断开连接的用户2分钟以上。唯一需要进行的编辑是SERVERNAME,我将其设置为排除Remote Desktop Broker服务器,但是可以排除任何您喜欢的服务器,或者根本不排除任何服务器。

顺便说一句,我的脚本是为Windows Server 2012 R2编写的。

该脚本执行此操作:

  • 获取所有远程桌面用户会话的列表。
  • 忽略任何不显示“ STATE_DISCONNECTED”的会话。
  • 忽略代理服务器(或任何其他服务器)
  • 忽略没有统一会话ID的所有会话
  • 忽略没有断开时间的任何会话
  • 对于那些具有断开时间的会话,它将检查当前时间,并且如果现在和断开时间之间的时间差大于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的文件,然后输入命令Reset Session%1 / server:%2并保存。

在命令提示符下,转到保存这些文件的目录,然后键入findsession用户名(您要查找的用户的登录名)。按Enter键,您应该看到登录名和会话ID。键入resetsession.cmd ID服务器名,它将重置该会话。我每天都用它,查找用户并重置会话非常快捷。


请使用文本格式选项来高亮命令,并增强可读性。这是一个很好的答案,但是请对其进行编辑。
Marco Marco

当命令太短而您仍然需要传递参数时,写批处理文件毫无意义
binki

1
  1. 通过找到会话ID qwinsta
  2. taskkill /FI "SESSION eq 1" /F假设要从qwinsta返回的会话ID为1,则终止会话下的所有进程。

这适用于Server 2012版本6.2 Build 9200,我希望它可以在所有版本的Windows上使用。


1

这个强大的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 '18

0

也许还有一个进程正在运行,阻止了注销进程。检查受影响的用户仍在运行的进程。然后一一杀死进程,看一巫婆是造成问题的原因。

还要检查HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run仅启动所需进程的注册表项。在64位中为HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run



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

不幸。我的用户会话已断开连接。任务管理器未显示任何以用户身份运行的进程。我无法从任务管理器中注销用户。我尝试了reset session id命令,并最终冻结了。我最终不得不以管理员身份在不同的会话中登录,删除该帐户并重新创建一个新帐户。


-1

您是否尝试从远程桌面服务管理器注销用户?转到管理工具->远程桌面服务->远程桌面服务管理器,然后注销会话。它可能会起作用。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.