One of the most useful technologies that Microsoft has incorporated into the Windows OS is Windows terminal services, which lets you remotely log on to a machine. After logging on, you can interact with the remote machine as if you were physically logged on to it. The remote machine sends all video output over the network to you, and your mouse and keyboard input is sent to the remote machine.
Systems administrators use terminal services because it lets them remotely perform work that they formerly had to sit at the machine to perform. Terminal services lets administrators defragment hard disks, install drivers, apply service packs, and perform other routine tasks from outside the computer room. Administrators and end users also use terminal services to access their machines from home. Regardless of the reason people use terminal services, tracking who is logged on to a particular machine is difficult. Thus, I've written a couple of scriptsWTSListUsers.pl and WTSLogoff.plthat can ease terminal services administration.
Listing Users
Jens Helberg's incredibly useful Win32 Perl extension Win32::Lanman (version 1.09 and later) exposes terminal services functions that let you list logon sessions, query for information about a given logon session, manage a user's terminal services logon rights, send a message to a logged-on user, and perform other administrative tasks. You can download the extension from http://www.cpan.org/modules/by-authors/id/J/JH/JHELBERG. My book Win32 Perl Programming: The Standard Extensions, 2nd edition, covers these functions in detail (http://www.roth.net/books/extensions2).
The script in Listing 1, page 2, lets you display a list of the users logged on to a given terminal services machine. To run the script, type
perl WTSListUsers.pl myserver
where myserver is the name of the terminal services server. The script then displays a list of users logged on to the terminal services server. For each user session, you'll see the username and domain. If the user is logged on over the network from a remote machine (as opposed to being logged on through the consoleaka the keyboard), the script also displays the remote machine's IP address, network name, display size, and color depth.
The script calls the Win32::Lanman extension's WTSEnumerateSessions() function (at callout A in Listing 1). The function accepts the name of the terminal services server and a reference to an array and populates the array with an anonymous hash for each terminal services session. The hash contains the session ID, the session state (e.g., the user is disconnected, logged on, shadowing), and the session's window station name.
Next, the script examines each session. One session will have a state of WTSListen (i.e., a value of 0x04). This particular session isn't a user sessionit's a session that's waiting for the next user to log ontherefore, no username is associated with it. The script ignores this session.
For each of the other sessions, the script calls the WTSQuerySessionInformation() function (at callout B). The script passes to the function the name of the terminal services server, the session ID, a reference to an array, and a reference to a hash. The array contains values that indicate which session information the function should obtain. For example, the constant WTSUserName (i.e., the value 0x05) indicates that the function should request the session's username.
The function populates the hash with keys and values that contain the information that the function requested. Note that not all the pieces of information are available for all the sessions. For example, a remote computer name isn't available for console sessions.