In environments in which you have roaming usersthat is, users who don't use the same computer every dayan important piece of information you might need to know is the machines that these users are logged on to. You need to know this information before you can remotely troubleshoot a problem (e.g., missing registry keys, missing environment variables) on a roaming user's computer.
By default, you can gather roaming users' machine information by filtering the Security logs on your domain controllers (DCs). However, this solution is time-consuming and potentially error prone, especially if you have two or more large Security logs. Instead, you can use one of two strategies to acquire this information. If you don't have too many computers on the network, you can simply poll each computer for the logged-on user. Alternatively, you can have users advertise the machines they're logged on to. By advertising I mean that the users can write to a central repository the name of the machine that they're logged on to. The advertising can be part of roaming users' logon script. Let's look at how you can implement both of these strategies and look at their advantages and disadvantages.
The Polling Strategy
If you have a small number of computers on the network (i.e., less than 50), polling each machine is the easiest way to determine the machine that a roaming user is logged on to. One approach is to use the Net View command to get a list of computers on the network, then use either the Nbtstat command or Sysinternals' PsLoggedOn utility to poll each machine to see whether the user is logged on to it. (PsLoggedOn is a utility that's part of Sysinternals' PsTools freeware suite, which you can find at http://www.sysinternals.com.)
Nbtstat uses NetBIOS over TCP/IP (NetBT) to display protocol statistics and current TCP/IP connections. The Nbtstat command's -a switch lets you obtain the name table of any remote machine you specify. (Note that the Nbtstat command's switches are case sensitive.) In the Nbtstat -a command's output, Messenger service names are followed by a <03> entry. In addition, when a user logs on with a domain account, the command output includes an entry with the user's ID. Thus, you can determine which computer a user is logged on to by running the Nbtstat -a command against a list of computers, then using the Findstr command to check the output for the existence of a <03> entry that matches the username you're interested in.
Based on this knowledge, I created the FindUser.cmd script, which Listing 1, page 12, shows. You can use this script on machines running Windows XP, Windows 2000, and Windows NT 4.0. To launch this script, you use the command
finduser.cmd username
where username is the name of the roaming user for which you're searching. The script stores the username parameter's value in the usertofind variable.
The For command that the code at callout A in Listing 1 shows uses the Net View command to obtain a list of computers on your network. The Net View command returns the computer names in the format \\computername (e.g., \\WKSTN1) as well as other output, such as headers. Because you're interested only in the computer names, the Find command filters the Net View command's output and keeps only those lines that contain the string \\.
For each computer name, the script runs the block of code labeled :findit, which the code at callout B shows. The :findit code determines whether the user you're looking for is logged on to that computer. This code first assigns the \\computername value from the For command that the code at callout A shows to the target variable. Because the Nbtstat command requires that computer names be without \\ characters, the line
Set target=%target:\\=%
replaces the \\ characters with nothing and assigns the edited computer name to the same target variable. The result is that the target variable now contains just the computer name.
Next, the :findit code runs the Nbtstat -a command against the computer name in the target variable. The code passes the Nbtstat -a command's output to the Findstr /i command, which searches the output for the string in the usertofind variable. The /i switch makes the search case insensitive. By default, Findstr returns any lines that contain the specified string. The :findit code redirects the Findstr /i command's output to NUL because you don't need this output. Instead, you need to determine whether the Findstr command executed successfully. Most shell scripting commands return a number, or error-level value, when they execute. You can use the If command with the Errorlevel clause to determine whether the preceding command executed successfully. An error-level value of 0 signifies success, whereas an error-level value of 1 or higher signifies failure. In this case, if %ERRORLEVEL% is equal to 0, Findstr found a match for the usertofind variable's value and the :findit code displays a message that specifies the name of the computer the user is logged on to. Note that this method won't work if the Messenger service is disabled, if the <03> UNIQUE type lists the computer name rather than the username, or if NetBT is disabled.