In the Inventory Solution documentation, there seems to be two methods to collect registry data using a custom inventory. One method uses the "key:" construct and the other uses the "reg:" construct. What is the difference between the two constructs, and are there any rules that should be followed?
To understand these two methods of collecting registry information using a custom inventory, it is helpful to review the registry structure. A good resource for this is from the Microsoft web site. A quick search of the website for "registry structure" gives the following link.
The basic objects in the registry are keys, subkeys and value entries. Keys and subkeys are arranged in a hierarchical fashion. Keys can have subkeys which in turn can have subkeys themselves. Although not required, every key can have "value entries" which are sometimes called properties or entries. These value entries have a name, type and value (or data). Perhaps the best way to visualize this is by reviewing the regedit display. In regedit, the left window contain keys, the right window contains value entries. The value entries on the right correspond to the key (subkey) that is selected on the left.
Every key may have a value entry that is unnamed which is called "(Default)". "(Default)" is displayed in regedit for every key even if it has not been set. Value entries can be of type String (REG_SZ), Binary (REG_BINARY), DWORD (REG_DWORD), Multi-String (REG_MULTI_SZ) or Expandable String (REG_EXPAND_SZ). Keep in mind that all types will be converted to string when output to a .nsi file during a custom inventory.
Using the "reg:" constuct
The "reg:" construct can only be used to output the value or data from a value entry. It is best used to return the value/data of a specific value entry for a specific key. The statement in the custom inventory would look something like:
One drawback is that the "reg:" construct cannot be used to obtain the key's default value entry.
Using the "key:" construct.
The "key:" construct is more versatile, but must be used within a “foreach” loop. There are two forms of the “foreach” statement.
foreach regkey= path=
The “foreach regkey= path=” statement is used to loop through the subkeys under a given registry key path. Within the loop, the “key:” construct can be used to output information relevant to that key, including its value entries. Example:
This code snippet would output the full path of each subkey, the name of the subkey and if set, the subkey’s default value. It would also output the value/data of the value entry named “Version” if the value entry existed in the subkey. When the “key:” construct is used with the “foreach regkey=” statement, three reserved words, keypath, keyname and default can be used. One other argument, “recurse=1” can be added to this form of the “foreach” statement so that it will recursively loop through all the levels of subkeys contained under the given registry path. (See KB 23929, https://kb.altiris.com/article.asp?article=23929&p=1)
foreach regvalue= path=
The “foreach regvalue= path=” statement is used to return data from the value entries for the given registry key (subkey) specified in the path. Only three pieces of data are available, the name, type and value. Example:
This code snippet would output the name, type and value of each value entry, including the default value entry. In the case of the default entry, the name would be blank.
Sample Custom Inventory
The attached custom inventory sample uses both forms of the “foreach” statement, one looping inside the other, to return all subkeys and value entries for a given registry key. The “recurse=1” reserved word has been added to the outside “foreach” loop so that all levels of subkeys are returned. The inside loop then returns all the value entries for each subkey encountered in the outside loop. Code has been added to output the literal string “(Default)” when the default value entry is encountered (i.e. the name of the value entry is blank).
Warning: The attached custom inventory sample should only be used on a small “branch” of the registry key tree. Collecting all keys and value entries from a large branch may take several minutes to execute and may consume large amounts of CPU.