In "Real-World Shell Scripting: Detecting and Inoculating Against Viruses," March 2002, InstantDoc ID 23934, I showed you how to use scripts to detect and inoculate your PCs and servers against viruses. You can also use scripts to make sure your antivirus software's virus-definition files and scan engines are current. Some antivirus products have automatic-update features. However, such features don't always work properly, so making sure that these updates are occurring correctly on every machine is advisable.

For example, my company uses McAfee VirusScan 4.5. Recently, the Help desk staff discovered that the virus-definition files were out of date on some desktop PCs, which meant the antivirus software's automatic-update feature wasn't functioning correctly. The team also discovered that a few PCs didn't even have the antivirus software installed. Thus, the Help desk staff needed to check all the PCs for problems and correct any problems found. Having the Help desk staff physically check and report on the status of more than 500 PCs would have been extremely time-consuming. Thus, I created the script GetAVProperties.bat to gather the virus-definition file's date for each PC. In addition, the script checks the version of VirusScan's engine. (Some of the engines are now obsolete.) The output of this script eliminated the legwork of trying to find the problematic PCs, which let the Help desk staff members concentrate on fixing the problems.

GetAVProperties.bat uses the Reg (reg.exe) utility to capture information about VirusScan's virus-definition file and engine. Reg.exe is available through several media, including the Windows 2000 Support Tools and Microsoft Windows NT Server 4.0 Resource Kit Supplement 4. Let's look at how GetAVProperties.bat uses reg.exe to capture the necessary registry information, how to run the script under different accounts, and how to customize the script for your environment.

Using the Reg Utility
To obtain the virus-definition file dates and engine version numbers, GetAVProperties.bat uses reg.exe to query the registries on remote Win2K and NT 4.0 machines. Reg.exe is powerful. You can use it to read, change, add, and delete HKEY_LOCAL_MACHINE and HKEY_USERS registry keys and values on remote computers. GetAVProperties.bat uses the Reg Query command to read the registry only. If you use reg.exe to modify the registry, carefully test your script in a nonproduction environment first, because running faulty code on production servers and workstations can cause serious damage.

You might find that a script successfully executes on one machine but fails on another machine. The most common reason for failure is path problems. For example, a utility that the script uses might not exist or might be in a different location on the second machine. Another common reason for failure is that the machines have different versions of the utility, which might mean that the syntax differs. The reg.exe versions that come with the Win2K Support Tools (Reg 2.0) and Supplement 4 (Reg 1.05) differ slightly in their syntax (e.g., the placement of the remote PC name differs).

Because I wrote GetAVProperties.bat to work in a mixed Win2K and NT 4.0 environment, GetAVProperties.bat uses the RegVer module to determine the correct reg.exe version to run. As Listing 1 shows, the module uses two For commands. Each For command executes the Reg command and pipes the Reg command's output to the Find command, which looks for the specified version number. If the version number is 2.0, the code sets the reg variable to 20. If the version number is 1.05, the code sets this variable to 105. Later, the script uses the reg variable's value to jump to the module that has the appropriate syntax for that reg.exe version. If the reg variable's value is 20, the script jumps to the Gf20 module. If the reg variable's value is 105, the script jumps to the Gf105 module, which Listing 2, page 6, shows.

If the Reg command returns a version number other than 2.0 or 1.05 (or no version number), the script displays the message Unable to determine reg.exe version, then exits. If you have a different version of reg.exe, you can still use GetAVProperties.bat if that version's syntax is compatible with the code in the Gf20 and Gf105 modules. To make that determination, you need to check the version's syntax for the Reg Query command by typing

Reg Query /?

at the command line. If the code in the Gf20 or Gf105 module follows the command's syntax, you can modify the RegVer module. For example, the syntax for the Reg Query command in Reg 1.0 is compatible with the code in the Gf105 module. Thus, you can change the code at callout A in Listing 1 to

For /f %%i in ('Reg ^|Find "1.0"')
Do Set reg=10x &&
Echo Using Reg version 1.0x
& Goto :EOF

As with any For command, this code needs to be a continuous line in the script.

Capturing the Necessary Registry Data
GetAVProperties.bat captures registry information about VirusScan 4.5's virus-definition file and engine. I found the VirusScan 4.5 registry data in the HKEY_LOCAL_MACHINE\SOFTWARE\Network Associates\TVD\Shared Components\VirusScan Engine\4.0.xx subkey. However, the subkey might differ in your environment. The easiest way to locate the correct subkey is to use regedit's Find function. I searched for the string 4.1.40, which was the VirusScan engine's version number on a representative test machine. When I discovered that the HKEY_LOCAL_MACHINE\SOFTWARE\Network Associates\TVD\Shared Components\VirusScanEngine\4.0.xx subkey contained both the engine's version number (the szEngineVer entry) and the virus-definition file's date (the szDatDate entry), I knew I had the correct registry location.

When I ran the Reg Query command with the subkey, the utility returned two lines that contained the data I needed and several lines that contained data I didn't want. Thus, I again used the For command to parse and filter the Reg Query command's output, as Listing 2 shows. The code at callout A in Listing 2 captures the virus-definition file's date and sets it to the FileDate variable. The code at callout B in Listing 2 captures the engine's version number and sets it to the Engine variable. In callouts A and B, note that the delims= option is followed by a tab and a space. Although the tab and space are default delimiters, Win2K handles this aspect of the For command differently than NT 4.0 does, so adding this delims= option is best. When you add the tab, be sure to press the Tab key and not insert an arrow symbol (*). I added the arrows in Listing 2 only to demonstrate the inclusion of the tab. When you open GetAVProperties.bat in Notepad, you should see large spaces rather than the arrows that Listing 2 shows.

After GetAVProperties.bat retrieves the FileDate and Engine variables' values, it displays those values on screen and prints them in a log. The script then increments capturedcounter, a counter that tallies the number of PCs for which the script successfully captured registry information. Besides capturedcounter, GetAVProperties.bat uses several other counters to record its successes and failures during a run. For a detailed explanation of counter usage, see the Web sidebar "Using Counters to Track Successes and Failures," InstantDoc ID 23064, which is part of the article "Real-World Scripting: Adding a Local Group," December 2001, InstantDoc ID 23042.

If a PC has a version other than VirusScan 4.5 or no VirusScan software at all, reg.exe doesn't return a value and the script sets the FileDate and Engine variable values to N/A. An N/A entry in the log tells the Help desk staff members that they need to look at that PC to determine what's wrong with the VirusScan installation. In addition, if the FileDate variable's value is N/A, the script displays the message Unable to locate the virus-definition file.

Running the Script Under Different Accounts
Running a script under different accounts can be helpful when the user account with which you've logged on doesn't have sufficient permissions to run a script. For example, suppose you have two accounts that you use to log on to the network. One account is a user account with typical user permissions. The other account is a local Administrators account, which you can use to access any machine in the domain. As Listing 3 shows, with the Net Use command, you can use the Administrator account to run GetAVProperties.bat and other scripts. However, hard-coding account information has a disadvantage: If you don't protect the script with the correct NTFS file permissions, users can access the script and obtain the passwords.

Note that the Net Use commands in Listing 3 will fail if you've already established a connection to the computer with your user account. To avoid this conflicting-credentials error, you can use the Net Use command with the /delete, or /d, switch to first break the current connection. Simply place the line

Net Use \\%target%\ipc$ /d

above the Net Use commands in Listing 3.

Customizing the Script
To use GetAVProperties.bat in your environment, you need to download the script from the Code Library on the Windows Scripting Solutions Web site ( and place the script on the machine on which you plan to run it. On that same machine, you need to install the Win2K Support Tools if it's a Win2K box or Supplement 4 if it's an NT 4.0 box. Finally, you need to customize the script by following these steps:

  1. Create an input file that lists all the PCs for which you want to obtain the virus-definition file's date and engine's version number. Put each PC name on a separate line so that the list looks like
  2. PDC1

    Save the file as pc-targets.txt.

  3. Configure the path to the input file. In the code
  4. Set targetfile=\\dom1pdc   virusresponse\pc-targets.txt

    replace dom1pdc\virusresponse\pc-targets.txt with your path.

  5. Configure the path to the log called pc-logfile.csv. In the code
  6. Set logfile=\\dom1pdc   virusresponse2\pc-logfile.csv

    replace dom1pdc\virusresponse2\pc-logfile.csv with your path.

  7. If you plan to run the script under the same account as the one you used to log on to the machine, uncomment the line
  8. :: Goto :GetFile

    in Listing 3. If you want to run the script under different accounts, configure the lines that callout A in Listing 3 shows. For each account you want to use, replace the sample passwords (e.g., help097, riverview), domains (e.g., %target%, domain1), and usernames (e.g., rootman, topdog) with the appropriate information. If you're unfamiliar with the Net Use command, see "Real-World Scripting: Adding a Local Group," December 2001, InstantDoc ID 23042.

  9. Configure the registry subkey in the For commands in the Gf20 and Gf105 modules, if necessary. Follow the instructions in the "Capturing the Necessary Registry Data" section.

I tested GetAVProperties.bat on Win2K Professional machines running Service Pack 2 (SP2) and NT Workstation running SP6A. Although the script captures the registry information associated with VirusScan, you can easily modify the script to capture registry information for other antivirus software.

A Useful Report
With GetAVProperties.bat, I was able to provide the Help desk staff with a useful report that let them concentrate on the problematic PCs. With a little adaptation, you too can use this script to save yourself or other people considerable legwork.