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.