Having the ability to use a terminal service (aka Remote Desktop) session to manage a Windows Server (2000, 2003, and 2008) is very useful. If you don’t have a Terminal Services license installed, you are limited to to two active sessions (plus a bonus connection that I’ll get to in a minute). If a person disconnects from a session without logging out, it can leave that session running. That allows you to start a long running task and come back to it later, but it does use up one of the available connections. If both sessions are being used, you will not be able to create a new terminal service connection to the server. At this point, you have three options:
Yell down the hallway and ask “Who has a connection to server XYZ”. This never works because either the person who left the connect forgot about it or didn’t realize that he (or she) was supposed to logout. The other problem is that you could be working from home and the only thing that the yelling accomplishes will be to attract your dog and your child, both of which will be looking for cookies.
Use the command line tools to identify the open sessions and kill one of them. There are two tools, qwinsta and rwinsta. If you run “qwinsta /?” from a command shell, you will get the following:</p>
qwinsta /?
Display information about Terminal Sessions.
QUERY SESSION [sessionname | username | sessionid]
[/SERVER:servername] [/MODE] [/FLOW] [/CONNECT] [/COUNTER]
sessionname Identifies the session named sessionname.
username Identifies the session with user username.
sessionid Identifies the session with ID sessionid.
/SERVER:servername The server to be queried (default is current).
/MODE Display current line settings.
/FLOW Display current flow control settings.
/CONNECT Display current connect settings.
/COUNTER Display current Terminal Services counters information.
If you run “rwinsta /?”, you get the following:
rwinsta /?
Reset the session subsytem hardware and software to known initial values.
RESET SESSION {sessionname | sessionid} [/SERVER:servername] [/V]
sessionname Identifies the session with name sessionname.
sessionid Identifies the session with ID sessionid.
/SERVER:servername The server containing the session (default is current).
/V Display additional information.
For the sample server XYZ, you would run “qwinsta /server:xyz” That will return something like:
SESSIONNAME USERNAME ID STATE TYPE DEVICE
console 0 Conn wdcon
rdp-tcp 65536 Listen rdpwd
gatesb 1 Disc rdpwd
rdp-tcp#93 jobss 3 Active rdpwd
From that output, we can take one of the IDs that was returned for the remote sessions and use rwinsta to kill that session. You would use something like:
rwinsta 1 /SERVER:xyz
And that will terminate that session, allowing you to open a new session. You will need admin rights to run that command, but if you are using the admin terminal service connections to the server, then you would already have the necessary access rights to the server.
There is a third option, you can connect to the console session. This is the bonus option that I had referred to earlier. This is the session that you would get if you were physically in front of the server and were logging in on the server’s mouse and keyboard. You can specify the console session as a command line parameter to the remote desktop client, mstsc.exe. The following syntax can be used to connect to the console session of a server:
mstsc /console
That feature will work with Server 2003 and later. On some machines, qwinsta and rwinsta may have been renamed to query.exe and reset.exe, respectively.
[Updated at 2:42 pm]
Steve listed an alternative to qwinsta and rwinsta on his blog. He uses quser.exe and logoff.exe, which provide pretty much the same functionality. On my machine, quser.exe was buried in c:\windows\system32\dllcache, which was odd. I wonder why it wasn’t in system32? quser has an advantage over qwinsta, it lists the logon time and idle time for each session. That gives you a little more data when you have to kill someone session and you can’t determine which one must die.