Administrators perform software audits to ensure that licensing agreements are followed, detect unauthorized software, and prepare for upgrades and migrations. To facilitate software audits, you can install a variety of third-party utilities and agents, some of which, in addition to gathering a list of installed software, can also collect information, such as the amount of free disk space, service status, and BIOS version, and even deploy software. However, at times you might want to remotely determine which software is installed on a workstation or server. The Control Panel Add/Remove Programs applet looks at one registry subkey (and its values), and you can query this subkey to display a list of installed applications. The script QueryInstalledSoftware.cmd, which Listing 1 shows, uses this querying process to easily and quickly perform a low-cost software audit.
Using Reg.exe to Query the Subkey
The HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall subkey contains the values that Add/Remove Programs uses to display a computer's installed software. You can use the reg.exe utility to remotely query this subkey. (Reg.exe used to be part of the Microsoft Windows NT 4.0 Resource Kit but now is part of Windows 2000 Support Tools.) You can also use reg.exe to locally and remotely add, delete, and update subkeys from the command line. The Uninstall subkey contains values that represent applications and contain information such as software name, installation source, and uninstall string. The displayname value contains the software name that Add/Remove Programs displays. To use reg.exe to query the subkey, you can type the following command on the command line:
Reg Query HKLM\SOFTWARE Microsoft\Windows CurrentVersion\Uninstall
/S \\compname
(Although this command appears on several lines here, you would enter it on one line on the command line. The same holds true for the other multiline commands in this article.) This command outputs all the Uninstall subkey values for the specified computer (compname). Because you don't need all this output, you can massage the output to display only the displayname values. The simplest way to do this is to pipe the output of the Reg Query command to the Find command: . . .