Downloads
43754.zip

Q: I'm trying to create a script to retrieve all the values under the HKEY_CURRENT_USER\\Software\Microsoft\WindowsNT\CurrentVersion\Devices registry subkey. I need to fetch each value name and its corresponding data and store this information in a Dictionary object or an array for later comparison. I tried using the Windows Script Host (WSH) Shell object's RegRead method, but RegRead requires that I know the name of each target value. In this case, I don't know the names because they can be different for each user. I thought I found a solution when Google pointed me to a Microsoft TechNet script that enumerates registry values and types (http://www.microsoft.com/technet/ community/scriptcenter/registry/ scrreg08.mspx). However, this script only retrieves each value's name and data type; it doesn't return the data assigned to each value. Can you help me enhance the script so that it also returns the data?

I'd be happy to. But before I do, let me take a moment to comment on your approach for the benefit of our fellow scripters. I like the fact that, rather than starting your script from scratch, you did your homework by locating some boilerplate code to help get you started. That's a very smart approach, and I encourage all scripters to use it whenever possible. Keep in mind that when you want to automate a routine task, there's a good chance someone has already been down the same path. For this reason, few tools are more valuable than a good search engine when you want to avoid creating scripts from scratch.

Your observation about the TechNet script is correct. The script enumerates all the value names and each value's data type under the target subkey, but it doesn't retrieve the data. However, this script is an excellent starting point for this task because most of the logic is already in place. You need to make only two primary changes to enhance the script so that it also returns the data:

1. Replace all the statements that write to the standard output stream (STDOUT) with the appropriate Windows Management Instrumentation (WMI) System Registry Provider methods (more on these methods shortly).

2. Add the value name and data to the Dictionary object.

You'll also need to make some minor changes. For example, you'll need to change the constants and variables that point to the target registry hive and subkey.

EnumerateRegistryValues.vbs, which Listing 1 shows, is an example of how you might modify the TechNet script to retrieve registry data. Perhaps the most challenging part of EnumerateRegistryValues.vbs is the five methods it must use to handle all the registry's data types. The System Registry Provider provides a different method for each data type:

  • GetBinaryValue reads registry values of type REG_BINARY.
  • GetDWORDValue reads registry values of type REG_DWOR
  • D.
  • GetExpandedStringValue reads registry values of type REG_EXPAND_SZ.
  • GetMultiStringValue reads registry values of type REG_MULTI_SZ.
  • GetStringValue reads registry values of type REG_SZ.
  • As the code at callout A in Listing 1 shows, all five registry methods use an out-parameter named varData to retrieve the target data. Unlike the more common in-parameters, which pass data to a method or function, out-parameters receive data from a method or function—hence the name out-parameter. You simply pass an out-parameter to a method or function. The method or function then populates the out-parameter with the data that's to be returned to the calling script.

    Note that the REG_BINARY data is returned in a byte array. If you want to convert this array into data that VBScript can read, you'll need to add code to do so. Use VBScript's AscB, LenB, and MidB functions to perform the conversion. For a sample script that demonstrates how to convert a byte array to a string, see the "Determine Logon Hours" script in the Microsoft TechNet Script Center (http://www.microsoft.com/technet/community/scriptcenter/user/scrug14.mspx). In addition, EnumerateRegistryValues.vbs doesn't include the error checking and recovery code that you'd likely include in a production-quality script. I'll leave adding that code to you as an exercise in error handling.

    So, there you have it—a script that retrieves registry data without knowing the value names in advance. If you want to learn more about the five System Registry Provider methods, see "Reading Entry Values and Types" in the Microsoft Windows 2000 Scripting Guide(http://www.microsoft.com/resources/documentation/windows/2000/server/scriptguide/en-us/sas_reg_sptf.mspx) or the StdRegProv topic in the WMI software development kit (SDK—http://msdn.microsoft.com/library/en-us/wmisdk/wmi/stdregprov.asp).