If you ever had to clean up old user profiles on shared PCs or locate all the PCs a specific user has logged on to for security reasons, the GetUser Profiles.bat script will be a valuable addition to your script collection. This script uses the NetUsers tool to enumerate user profiles on PCs. Even if you don't need to enumerate user profiles, GetUserProfiles.bat is valuable in that it demonstrates how to error-proof paths and perform advanced string manipulations.
How to Error-Proof Paths
Script errors are often caused by problems with pathnames to input, output, and utility files. Common problems include paths enclosed in quotes, incorrect paths, and paths with embedded spaces. GetUserProfiles.bat demonstrates how you can error-proof your file paths against these problems.
Dealing with paths enclosed in quotes. When people enter input file paths in scripts, they often enclose the path in quotes. Although that's typically the proper way to handle paths, it can cause problems if you've written a script that adds quotes when they're necessary. Having duplicate quotes can cause a script to fail.
The best way to deal with this situation is to assume that a script's user has entered quotes, use a string-replacement operation to remove them, then add them back in. This technique ensures that the script works correctly regardless of whether the user enters a file's path in quotes. Callout A in Listing 1 shows this technique in action. Note that the outside set of quotes effectively adds the quotes back in.
Dealing with incorrect paths. If you run scripts regularly, you've likely seen the dreaded File Not Found message scrolling across your screen because you entered an incorrect path to a file or tool. The best way to eliminate this problem is to run a test to determine whether the file exists at the specified location. For input files and tools, you can test for file's existence and exit the script with an error message if the file isn't found, as callout B shows. For output files, you need to take a slightly different approach because scripts often create output files near the end of their run time. One approach is to simply test for the existence of the folder in which the output file will be created. Another approach is to create the output file early in the script, write a line that contains header information, then test for the file's existence. This solution tells you not only whether the file exists but also whether it's writeable. As callout C shows, GetUserProfiles .bat uses this approach.
Dealing with paths that contain embedded spaces. There are some utilities, including NetUsers, that don't work correctly when you execute them from within in a For command and the utilities' paths include spaces. You can prevent such problems by converting the paths to an 8.3 format. To do so, I first tried to use the %~s1 batch parameter with the For and Call commands but had mixed results. (Failures sometimes occurred when attempting to get the short path while there were still spaces in the filename.) So, I settled on a more reliable approach in GetUserProfiles.bat. As callout D shows, the script first uses the Dir /X command to get the 8.3 filenames, then calls the getshort routine. This routine, which callout H shows, strips off the long filenames from the original pathnames that the user entered, leaving just the long paths to the folders in which the files are stored. The routine then obtains the 8.3 versions of the long paths. Finally, the routine combines the 8.3 filenames and the 8.3 paths to get the entire pathname in a short format. Although writing this code requires a bit of work on the front end, it can eliminate problems later on.
When you perform 8.3 path conversions, you need to make sure that you correctly sequence your scripts. It might be tempting to convert the files' paths to an 8.3 format before checking for the files' existence. However, if you do so, you'll discover that Call, For, and Dir commands don't work correctly. Always test for files' existence before you perform any 8.3 conversions.
How to Perform Advanced String Manipulations
As mentioned previously, GetUserProfiles.bat uses NetUsers. This free utility is available from SystemTools.com, which has a number of interesting freeware tools. You can use NetUsers to query a local or remote computer for a history of the users who have logged onto the machine. The good news is that this tool retrieves their user IDs, friendly names, and last logon date and time. The not-so-good news is that although the NetUsers output is easy to read on screen, it's difficult to work with when you redirect it to a file.
For example, let's say you want to get the history of the users who have logged on to a remote computer named WORK1, so you run the command
NetUsers.exe \\WORK1 /h
The /h switch tells NetUsers to display the users who have logged on in the past. Without this switch, NetUsers displays only the currently logged on user. Figure 1 shows this command's output, which has been redirected to a file. Note that the Connecting to line is returned only when accessing remote computers and is seen only when the output is redirected to a file.