Windows NT Server 4.0, Terminal Server Edition has been available for almost a year, and administrators are fitting the OS into networks throughout the NT world. Microsoft designed Terminal Server to attract Citrix WinFrame users who are looking for an NT 4.0 thin-client product. Terminal Server has succeeded in interesting many WinFrame customers, and it has brought many new administrators into the multiuser-NT fold. (For more information about Terminal Server and WinFrame, see "Related Articles in Windows NT Magazine," page 78.)
Terminal Server includes all of NT's graphical administrative tools. NT's point-and-click utilities, including User Manager, Server Manager, and NT Explorer, make learning to administer Terminal Server systems a breeze. These GUI tools are wonderful for new administrators and small projects, but administrators of large networks need command-line alternatives.
Veteran NT administrators know that one of NT's primary weaknesses is its lack of command-line alternatives to GUI utilities. Administering an NT network from the command line is impossible without Microsoft Windows NT Server 4.0 Resource Kit tools such as Addusers, Rmtshare, and Xcacls. (For information about these utilities, see "AddUsers," May 1998; Reader to Reader, February 1998; and "XCACLS," March 1998.) WinFrame has always offered better command-line tools than NT has offered, and Terminal Server includes much of WinFrame's command-line functionality. As far as I can tell, Microsoft hasn't documented Terminal Server's command-line tools, but as I've hacked around on my Terminal Server systems, I've found some useful utilities. Because I use RDP on my network, I'll cover the Terminal Server commands that work with both RDP and WinFrame's Independent Computing Architecture (ICA) protocol.
See Whether a User Is Logged On
The Query User tool gives you information about users' connections to a Terminal Server system. Want to know whether a user with the NT username janesmith is attached to the server Shipboard? Open a command prompt on any Terminal Server machine in Shipboard's domain, and type
query user janesmith /server:shipboard
If Jane Smith isn't logged on to Shipboard, Terminal Server will respond with the answer "No User exists for janesmith." If she is logged on to Shipboard, you'll get information about her. You'll see her username, her Terminal Server session name (a string such as rdp-TCP#1), her session ID (a number that identifies the session), the number of minutes her session has been idle, and what time she logged on. The session ID that Query User provides is important; you need it to run some of Terminal Server's other command-line utilities.
Query User's syntax looks like
query user \[
\] \[/server: \]
The identifier variable can be a user's username, session name, or session ID. Any one of these three identifiers gives Query User enough information to find a particular user session. If you type
without an identifier, you'll get a list of the users who are logged on to your server. (You can use an alternative Terminal Server utility named Qwinsta to list all of a server's sessions—including not only active user sessions but other sessions that the system runs for its own purposes.)
Without the /server: parameter, Query User gives you information about the people logged on to the server that you're sitting at. To query a different server, add /server: and the name of the server you want to query. For example, to remotely request a list of the people attached to a server named Pungo, you type
query user /server:pungo
I haven't found a way to ask Terminal Server to search every server in a group for a particular user; telling Terminal Server "See whether janesmith is logged on to any of this domain's Terminal Server systems" seems impossible.
Locate Machines Running Terminal Server
If you need to find a user and don't know which Terminal Server system the user is connected to, you must individually query each Terminal Server system in the domain. The Qappsrv utility can help you with this task by providing you the names of all the Terminal Server machines in your domain. Qappsrv's syntax looks like
qappsrv \[/address\] \[/domain:
You need the /domain: option only if you're querying a domain other than the domain you're working in. Qappsrv's /address option yields two pieces of information about each server in the domain: its media access control (MAC) address and a mysterious Network field. When I type the command line
I always get servers' correct MAC addresses, but my servers' Network column is invariably blank. I suspect that the Network column lists an IPX network number, and the column is blank on my systems because my network uses TCP/IP.
Log a User off a Terminal Server System
Suppose you're looking for Jane Smith because you discovered she has been using your company's silicon for sinister purposes and you want to knock her off the server. You need her session ID or session name to zap her connection, so first you need to use Query User to find one of those parameters. Then, you're ready to disconnect her.
If Jane is in a session on a server named Kempsville and her session ID is 10, you can get rid of her from any server in the domain with the command line
disconn 10 /server:kempsville
Obnoxious, you say? Perhaps. But you don't need to worry about losing data in the applications Jane is working in. The Disconn utility terminates a user's Terminal Server session, but it doesn't shut down the programs that the user is running. If Jane clears her good name, she can reconnect and resume her work right where she left off.
Disconn protects the work of the person you're disconnecting, but it also sucks up memory on the Terminal Server system. If disconnection isn't enough for you and you just want to bring the hammer down on a session, use the Reset utility. To disconnect Jane Smith and close all her Terminal Server applications, type
reset session 10 /server:kempsville
Reset shuts down the disconnected session's running programs, and it doesn't ask users whether they want to save data before it disconnects them. Use Reset cautiously.
As you can see, Disconn and Reset have similar syntax:
Both utilities require the identifier variable to be either a user's session ID or session name; Disconn and Reset can't identify a session by username. Like Query User, Disconn and Reset require the /server: parameter only if you issue the command from a remote server.
Ask a User to Log Off
Suppose you don't really have any evidence against Jane Smith. You're just suspicious that she's acting unethically, and you want her off the server so you can snoop around. How can you send her a realtime message? Terminal Server's Msg command-line tool sends messages and even waits for user responses.
Msg's syntax looks like
\] \[/w\] \[/server: \]
Msg has lots of options. Msg accepts as its identifier variable a username, a session ID, a session name, or a filename preceded by the at (@) character. Like many of Terminal Server's other command-line utilities, Msg runs on the server you're working from unless you specify the /server: parameter.
You can use Msg to send a message to Jane by typing
msg janesmith Jane, we're bringing the server down. Please log off.
Or you can use the /w option to make sure Jane sees the message. If you type
msg janesmith /w Jane, we're bringing the server down. Please log off.
your Terminal Server system doesn't have a command prompt until Jane responds or until the Msg command times out. Msg's default timeout value is 60 seconds, but you can specify a different length of time (in seconds) with the utility's /time: parameter. For example, to give Jane 2 minutes to respond, type
msg janesmith /w /time:120 Jane, we're bringing the server down. Please log off.
You can pester all of a server's users by using an asterisk (*) as the Msg command line's identifier:
msg * Everyone log off the server immediately.
Or you can send the message to a list of users by putting the target users' names in an ASCII file that has one username per line. Then, you use the @ character and the name of the ASCII file as the Msg command line's identifier. For example, to send a logoff message to several people, you can create an ASCII file named manyfolks that lists the users you want off the system, then use this command line:
msg @manyfolks Everyone please log off.
The only problem with sending messages to multiple users is that if you add the /w option, Msg works sequentially. The utility sends the message to the first person on the list and waits for the first user's response or for Msg to time out before sending the message to the second person on the list.
Keep New Users from Logging On
One smooth way to bring an NT file server offline is to pause the machine's Server service. Pausing the Server service prevents new attachments but doesn't kick any current users off the server. After you pause the service, you can send messages to the server's users and make sure all users are off the system before you stop the Server service.
How can you tell a Terminal Server system to stop accepting new connections but not to disconnect current users? The OS includes a Terminal Server service, but it doesn't let you pause the service. Dropping the number of server connections in License Manager for Terminal Server doesn't seem to work, either. But Terminal Server's Change Logon command-line tool provides the same functionality as pausing NT's Server service. Just open a command line on the Terminal Server system, and type
change logon /disable
The server will reject all logon attempts, but the action won't affect users who already have sessions on that server. You can add a /server: parameter to tell Change Logon to work on a remote system. When you're ready for your Terminal Server system to begin accepting new connections again, use Change Logon again, but replace the utility's /disable option with its /enable option.
Keep New Users from Logging On
The Shutdown utility lets you remotely shut down or reboot a Terminal Server system. Shutdown's syntax is
Shutdown's /reboot option reboots the server. Shutdown's /powerdown option turns off the computer if the system has NT Advanced Power Management (APM) drivers; otherwise, the /powerdown option shuts down the server's processes and displays a Click to restart message.
By adding a time parameter, you can tell Shutdown to notify users and then wait for a specified time period before terminating their sessions. For example, the command line
shutdown 120 /server:princessanne /reboot
instructs Terminal Server to tell all users with sessions on a server named PrincessAnne that the server is going down, to wait 120 seconds, and to reboot the machine.
Find Out Who's Using an Application
Suppose your server is behaving strangely. You suspect the problem is that a lot of people are running Wtsquake (a hypothetical Terminal Server version of the game Quake) and that the game is hogging the server's CPU power. What can you do? You can use Terminal Server's Qprocess tool. Qprocess reports which processes are running on a Terminal Server system at any moment.
You can use Qprocess in several ways. First, you can find out which programs a particular user is running. Qprocess takes a username, session name, or session ID as a user identifier. If you suspect the mischievous Jane Smith of playing too much Wtsquake, type the command line
to find out which programs she's running. In response to this command line, Terminal Server will list all the processes that Jane is running and will provide each process' process ID. Hang on to the process ID for every process you want to stop.
If you see Wtsquake's filename, wtsqk.exe, on Jane's Qprocess list and want to find out who else is running the game on your Terminal Server system, you can run the Qprocess utility again, using the process name as the identifier variable. Qprocess uses the terms process and program interchangeably. A program can consist of two or more processes, but most clientside applications consist of only one process, so you can usually just enter a program's filename as the Qprocess identifier. Include the file extension in the process name. If you type
Qprocess will expose all your server's Wtsquake players.
Stop an Application
Once you know who's playing Wtsquake, you can stop the players' game with Terminal Server's Kill tool. Kill can find and eliminate all instances of a process or let you shut down a particular user's instance of the process.
In its simplest form, Kill looks like
Kill takes a process ID or process name as its identifier variable. When you enter a process name in Kill, use only the first part of the process' name; don't include the file extension.
If you use Kill with a process name, as in
you'll terminate only processes in your Terminal Server session. To tell Terminal Server to seek out and terminate all processes with that name in all of the Terminal Server system's sessions, use the /a option.
kill wordpad /a
stops WordPad in all user sessions on the server you're working from. Kill also has a /server: option, which you can use to tell the utility to run on a remote server.
How can you stop WordPad for one specific user? First, use Query User to find the user's session ID. Then, use the /ID: option like so:
kill wordpad /ID:
Finally, you can add the /v option to make Kill a more chatty executioner. If you use /v, Kill identifies particular instances of a process before it zaps them.
Someday, administrators will be able to perform almost every NT administrative function from the command line. When that time comes, you'll be able to administer a big network entirely through batch and shell programming. NT isn't close to offering complete command-line administration, but Terminal Server's wealth of command-line utilities lights the way for administrators of large networks. If you run Terminal Server, explore the OS's undocumented command-line capabilities. All the commands I've explained have many options—more options by far than I have space to cover. Try the /? option after any of the commands I've listed to learn more about the utility's capabilities.