22

I'm looking for some ideas on how to disconnect, logoff, or reset a user's session in a 2008 Terminal Server (unable to login as the user either as it is completely locked-up). This is a production environment, so rebooting the server or doing something system-wide is out of the question for now. Any Powershell tricks to help us with this?

We've tried to disconnect, log the user off and reset the session as well as killing the session's processes too, directly from the same terminal server (from the task manager, Terminal Services Manager and the Resource Monitor) with no results.

Help!


UPDATE: We ended up rebooting the server as no other attempts that we could think of worked. I'll leave this question open hoping someone might have more information about this one issue, and it's potential fixes

4
  • 2
    I have the exact same issue on my windows 2008 R2 SP1 Terminal servers. They just randomly hang and users are unable to logoff or logon to the server. I cannot log on localy as local admin or domain admin. The only way to connect to the server is using compmgmt.msc but even here I cannot see any issues in the event logs. At some stage I get a message saying the IMA service is not responding and the server has been removed from teh farm. The only way to resolve this is to reboot the server Hard. Power off and back on again. I have not been able to narrow the cause of this down to anything and i
    – user81969
    May 19, 2011 at 10:02
  • 1
  • 1
    Potentially useful links for anyone encountering this issue going forwards
    – JohnLBevan
    Aug 22, 2014 at 18:18

24 Answers 24

8

What worked for me to resolve this same issue was to kill off all the processes running under the locked account from under Task Manager and then I was able to simply log off that account (from an Administrator account).

The user was then able to log back on under the account.

No reboot was necessary and no third party software needed to be downloaded.

3
  • -Thanks, saved me from rebooting the server! Really didn't want to kick everyone out during the workday because of 1 stuck session.
    – MAW74656
    Apr 10, 2015 at 15:57
  • Is it safe to kill these processes? My user has csrss.exe, dwm.exe, LoginUI.exe, and winlogon.exe. I thought that killing winlogon.exe would trigger a BSOD…
    – binki
    Aug 14, 2018 at 15:17
  • I wanted this to work for us, but it didn't. We ended up rebooting. :( Sep 29, 2021 at 12:56
6

I want to share how I reset of the account without the need to reboot the server. First of all you need to have administrator access to the server. I use the following logon option: mstsc /v:servername /console /admin in order to access the server. Then in "Windows Taks Manager", go to the Users tab and proceed to do a right click over the account that you want to "Log Off", select log off. This should free the locked session used by that account.

2
  • 1
    except it doesn't always. Plus the OP said they already tried this. Jul 20, 2018 at 6:05
  • For this issue, the Sign Out button in Task Manager→Users does nothing.
    – binki
    Aug 14, 2018 at 15:15
5

The simple answer is to run an elevated command prompt and type "Taskmgr" and then it will allow you to logoff the sessions under the USERS tab. It will not work without being in the elevated session.

2
  • Tested & that solution worked.
    – Overmind
    Oct 27, 2016 at 5:16
  • 1
    Not for me. Also cannot use taskmanager as administrator to kill any of the user's processes either. Jul 20, 2018 at 2:05
3

You can start a cmd, do a query session, check the id of the session to be killed and then do a reset session. For instance, if with query session you get that the session name rdp-tcp#1 is the one you want to kill, then you can execute reset session rdp-tcp#1 and get it killed.

2
  • Thanks, but that didn't help either.
    – l0c0b0x
    Jun 14, 2010 at 18:29
  • When I run reset session 9 that command just hangs. My session continues to have the four processes running without appearing to be active: crss.exe, dwm.exe, LogonUI.exe, and winlogon.exe. i.imgur.com/cFM62RA.png and query session 9 outputs No User exists for 9.
    – binki
    Aug 14, 2018 at 15:31
3

I suppose the same happened today on my Win2008R2 Terminal Server. Sympthoms were: 1. He phoned me with "'connecting' message just hangs forever". He's just a simple user so I can't expect detailed problem description. 2. Tried logging off/resetting session (which usually helps in these cases) - did not work. The session still hangs in the list with 'disconnected' status. 3. Tried killing all processes for that user - did not help. Session persists and refuses to get killed.

Solution was - connect as user (login with his credentials if you can reset his password or use some kind of remote assistance to see what happens on his computer) and see what happens in logon window. When connecting I clicked on RDP Client's 'details' button - and here it was, a error message that winlogon did something wrong, it was waiting for user to click on 'retry/ignore/etc' buttons and since it's the omnipotent winlogon it caused all that weird behavior.

p.s. I could not found any way to really force kill a session :(

2
  • This fixed it for me! It was waiting for the user to choose to disconnect another user or hit cancel. I hit cancel and now that User which was stuck in Task Manager’s Users tab disappeared. Thanks!
    – binki
    Aug 14, 2018 at 15:33
  • This is what my situation looked like when this was the issue: i.imgur.com/W6eO5wW.png i.imgur.com/EpPwyJc.png i.imgur.com/cFM62RA.png Also, I’m using Windows Server 2016
    – binki
    Aug 14, 2018 at 15:41
3

We just had a similar issue with our Windows Server 2008 R2 Remote Desktop server. The user session showed "Active" when looking at RDS Manager, but did not have the associated session ID# or connected device showing (both were blank).

All of the tricks above did not resolve the issue. When connecting as the user in question, an error message came back stating that the Terminal Server was busy and to try again later or contact the administrator.

We wound up rebooting the server as well.

3

I had the same issue in Windows Server 2016. The user was not able to login.

So I tried the following steps to disconnect the orphaned session:

  1. on the CLI qwinsta lists all available sessions, inactive and active ones, there is one disconnected session (called "getr." in the screenshot) without a user name, but an session id.

show active sessions and kill them

  1. with the session id (7) from 1. I tried to kill this session with either reset session 7 (fyi: rwinsta is an alias for reset session)

  2. it worked for one session, but the next time it just had no effect, so I opened the task manager and the user tab. There you find one expandable list assigned to every remote desktop user - one list had no user name in it and only showed 4 tasks running.

  3. I tried the obvious one: Logging off the user. Without any effect.

trying to logoff the user

  1. So I tried to end those 4 tasks assigned to this user. Be careful, because some tasks, most importantly csrss.exe, when killed, also would result in a reboot of the system. I skipped them and just killed some obvious RDP-tasks.

After Step / Try 4 even the last crashed session was killed and the user was able to login again

  1. If this is still not working, try this solution from another question: When you connect with the RDP client, click it's "details"-button. There you should see an error and you can even click retry or ignore.
4
  • Can you be more specific about which processes you killed and which ones not to kill? I think that I should skip winlogon.exe but am unsure about others like LoginUI.exe, csrss.exe, and dwm.exe.
    – binki
    Aug 14, 2018 at 16:08
  • The symptoms for the second session you had sound similar to mine and serverfault.com/a/176080/164429 . You could probably add “Connect” as a step to try for a more complete solution and maybe even avoid needing to kill processes.
    – binki
    Aug 14, 2018 at 16:09
  • @binki it should be "csrss.exe" - if you kill this process, the system will restart.
    – n.r.
    Aug 15, 2018 at 7:59
  • Step 1 followed by Step 2 worked for me. At least I think so. The reset session command did never return. I had to ^C. But the user was connecting again and problem solved. Task manager, killing the session, killing processes, elevated or not, did not work. Jan 13, 2022 at 18:05
2
  1. Locate the session ID with qwinsta.
  2. Kill all processes under the session taskkill /FI "SESSION eq 1" /F, assuming the session ID you wanted to end returned from qwinsta was 1.

This worked on Server 2012 Version 6.2 Build 9200, I would expect it to work on all version of windows.

1
  • This was the only option that worked for me.
    – Abid
    Sep 23, 2022 at 12:19
1

It may be worth checking that the user doesn't have a credentials pop-up box hidden behind the remote desktop window with alt + tab.

A coworker was having the same issue; couldn't log-off, or reset, and all of his processes were manually shut down. When I tried to access the gui for the system he was remoting FROM, I found a credentials box hiding behind the remote session.

1

I'd the same situation: a Windows Server 2008 R2 with Remote Desktop Services, RDP connection set up to log off users after the session is inactive or disconnected 3 hours, and still some sessions remained locked. I tried to log them off with both Remote Desktop Manager and qwinsta/quser, with no success.

Here's how I resolved it:

  1. I've located the session ID with qwinsta.
  2. I've located the PID of winlogon.exe for the hung session with query process /ID:yourid.
  3. I've killed the process with taskkill /f /PID yourPID.

Way to go. I'd like otherwise to find a solution for this to not happen.

1

What worked for me was :

  • log on the server
  • open task manager
  • look for the user in the user tab
  • right-click, connect, enter the user password, I saw a 'Please wait' screen
  • press alt-tab, that logged me off from the server and logged off the user too
1

I had this issue with locked Remote Desktop Application users. I wrote this Powershell script to run on a scheduled task to log off users that showed as disconnected for more than 2 minutes. The only edit that is required is the SERVERNAME which I set to exclude the Remote Desktop Broker Server, however you can exclude any server you like, or none at all.

My script was written for Windows Server 2012 R2, by the way...

The script does this :

  • Gets a list of all Remote Desktop User Sessions.
  • Ignores any sessions that do not say "STATE_DISCONNECTED".
  • Ignores the Broker Server (or any other server)
  • Ignores any sessions with no Unified Session Id
  • Ignores any sessions that do not have a disconnect time
  • For those sessions that have a disconnect time, it checks the current time and if the time difference between now and the disconnect time is more than X minutes (in this case 2), kills the winlogon process.
  • It also attempts to issue a log off command (This will most likely fail after the winlogon process is killed).

It works for me! I hope it helps someone else! :)

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'
            }
         }
      }

Or if you prefer a version that you can see what is happening on the screen :

 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

Create a file in notepad and call it findsession.cmd. Place the command Query Session /server:servername | find /i "%1" and save to a directory. Create another file called resetsession.cmd and put the command Reset Session %1 /server:%2 and save.

From a command prompt go to the dir you saved those files in and type findsession username (login of user you're trying to find). Hit enter and you should see the login and session ID. Type resetsession.cmd ID Servername and it will reset that session. I use this daily and it is super fast for finding users and resetting their sessions.

2
  • please use text formatting options to highligh commands, and empower the readability. It is a good answer, but please, edit it.
    – Marco
    Sep 15, 2017 at 16:49
  • There’s no point to writing batch files when the commands are so short and you’d need to pass them arguments anyway
    – binki
    Aug 14, 2018 at 16:07
1

This power-shell script worked for me, it even gives a nice log file. I got it from here.: I hope this will help someone else since the other answers had a lot of prerequisites and or did not work for me.

    # .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"  

Edit:
I originally used this script to log-off and close all the "disconnected" sessions. We have a couple of terminal server applications with many users and limited licenses. The disconnected sessions would stay open for a very long time and sometimes it would stay open indefinitely. This resulted in unused sessions which would take up some of the licenses and other users would then not be able to connect as a result.

  • I run the script using a scheduled task to regularly check and
    disconnect sessions on some of my servers. It works autonomously
    without any interaction needed.
  • I use it on Windows 2008 R2 Server and Windows 2012 R2 Server operating systems.
  • It only closes sessions which was disconnected.
  • It updates a 'log' file with the users or sessions which it disconnected.
2
  • Could you explain what it does? Aug 15, 2018 at 8:50
  • 1
    Hi Konrad, I edited the answer a bit and hope that it explain what the script does. Basically the script closes all the disconnected sessions which remains open after a remote user disconnects from the server.
    – Roan
    Aug 16, 2018 at 5:33
1

For those who prefer a UI way of doing this.

  1. Download SysInternal suite. (https://docs.microsoft.com/en-us/sysinternals/downloads/sysinternals-suite)

  2. Launch procexp64.exe in Admin mode

  3. Click on "Users" and select the user in question. Click on "Properties"

enter image description here

  1. Note the Session ID

enter image description here

  1. Go back to the main screen. Right click on the header of a column. Click on "Select Column"

enter image description here

  1. Go to "Process Image" tab. Click on "Session" check box. Click OK

enter image description here

  1. Click on the Session column header and find the Session from the box above.

enter image description here

  1. Start killing each process. Some will say you cannot stop it, just continue to the next one. Eventually the ones that could not be stopped will stop by themselves.
0

Maybe there is a process still running, blocking the logoff process. Check the still running processes for the affected user. Then kill process one by one to see witch one is causing the problem.

Check also the HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run Registry key that only needed Processes are started. In 64bit it is HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run.

0

You can download the "Process Explorer" tool from Microsoft and use that to solve your problem. If you have the session IDs, you can find their respective processes. Then if a user session is disconnected, you can kill the process with Process Explorer.

0

Not exactly the same environment (we have 2012r2) but restarting the Hyper-V Virtual Machine Management service (VMMS) released the connection for me.

0

You need to click to on process and show process from all users and then you will be able to disconnect.

why don't to create a session policy under Remote desktop session host configuration end disconnected or idle session after certain interval.

0

My fix: On a different network sever i connected to the problem server via Computer Management tool, in open sessions I right clicked and closed every open file then was able to connect via mstsc

0

you could always use powershell from your local machine and do it remotely

Invoke-command -computername <servername> -Credential (get-credential) { 
    $session = ((quser | ? { $_ -match <username> }) -split ' +' )[2]
    logoff $session
} 
1
  • To make your answer even more useful it would be helpful to provide a basic explanation of how this command works. Not everyone may be experienced enough with PowerShell to understand it. Thanks for contributing. May 19, 2017 at 22:01
-1

Unfortunately. My user session was disconnected. The task manager did not show any processes runing as the user. I could not log the user off from the task manager. I tried reset session id command and ended up freezing up as well. I had to end up logging in in a different session as the administrator, deleting the account and re-creating a new one.

-1

Have you tried to logoff de user from de Remote Desktop Services Manager? Go to Administrative Tools --> Remote Desktop Services --> Remote Desktop Services Manager and log off de session. It may work.

-1

Go to start window and click on your name

See sample here

2

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .