Whenever I talk or write about using registry changes to troubleshoot problems, people ask the same question: "How do I make a registry change on multiple computers without traveling to each machine?" To distribute registry modifications across the network, you can use one of three methods: imported registration (.reg) files, regini.exe, or group or system policies.
Before I discuss these options, I'm compelled to give the usual warning: Messing with the registry is dangerous. Don't try any of these suggestions unless you're comfortable with the registry and you qualify as a power user. Before you begin, you can use regedit.exe to export a key as a backup measure. The exported file carries the .reg extension. Importing the file back into the registry is a quick way to repair the damage if your manipulation of the key causes problems. (Even if you prefer to work with regedt32, you should open regedit first and export the key you're going to tweak. Regedit's export and import features are easier to use than regedt32's equivalent backup procedures.)
You can apply many user and computer restrictions through Group Policy Editor (GPE—in Windows 2000) or System Policy Editor (SPE—in Windows NT and Windows 9x). This article assumes that those resources don't already include the changes you want to make and that registry tweaks are your best option.
Option 1: Create or Export Registration Files
You can distribute .reg files that users can then import into the registries of target computers. All you need to do is create—or use regedit to export, then edit—the .reg files, then distribute them. (Registration files have one serious shortcoming, however: They can't delete anything in the registry. See the sidebar "A Registration File Drawback," for details about this limitation.) Format the registration file's contents as follows:
<RegistryEditorVersion> <Blank line> \[<RegistryPath>\] "<DataItemName>"="<DataType>: <DataValue>"
RegistryEditorVersion is whichever version of regedit.exe you're using. This entry identifies the file as a registration file. Regedit automatically adds this information when you export a .reg file, but you must manually enter the information when you create a .reg file. For Win2K, the RegistryEditorVersion is Windows Registry Editor Version 5.00; for NT 4.0, the version is Regedit4.
Blank line identifies the beginning of a new registry path. (Each individual key or subkey is a new registry path.) When you export a key, the .reg file displays a blank line before each key or subkey. If you have multiple keys in your .reg file, blank lines can help you examine and troubleshoot the contents. (Microsoft's instructions state that the blank line is necessary. However, when I create .reg files and inadvertently forget the blank lines, the files still merge successfully.)
RegistryPath is the path to the key that holds the values you're importing. Enclose the path in square brackets, and separate each level of the hierarchy by a backslash—for example, \[HKEY_LOCAL_ MACHINE\SOFTWARE\Policies\Microsoft\ Windows\System\]. A .reg file can contain multiple registry paths.
When the bottom of the hierarchy that you enter in the path statement doesn't exist in the registry, you're creating a new subkey. Registry files' contents are sent to the registry in the order in which you enter them. Therefore, if you want to create a new key and a subkey below that key, be sure to enter the lines in the proper order. (However, the only reason to create new keys is because you've written software that looks for those keys. Creating new keys isn't a task you perform for system maintenance.)
DataItemName is the data item you want to import. When a data item in your file doesn't exist in the registry, the .reg file adds it (with its value). When a data item does exist, the value in your .reg file overwrites the existing value. Quotation marks enclose the name of the data item. An equal sign (=) immediately follows the name of the data item.
DataType (i.e., the imported item's data type) immediately follows the equal sign, unless the data type is of REG_SZ (REG_SZ types are strings). For all data types other than REG_SZ, a colon immediately follows the data type. Table 1 shows the entries for five common data types. (Nine data types exist, but the types in Table 1 are likely to be the only ones you'll use for system maintenance.) For information about these data types, see the sidebar "Registry Data Types," page 70.
DataValue (i.e., the value you want to import) immediately follows the colon and must be in the appropriate format (i.e., string or hexadecimal—use hex format for binary data items). You can enter multiple data-item lines for the same registry path. For example, the data-item lines
"GroupPolicyRefreshTime"=dword: 00000014 "GroupPolicyRefreshTimeOffset"= dword:0000000f
reflect the hex entries that these data items require: 00000014 is the hex equivalent of 20, and 0000000f is the hex equivalent of 15. If you're uncomfortable with hex or other nonreadable data, restrict your .reg file creation efforts to items that are neither binary nor hex format.
The registry doesn't have a Boolean data type (although it should, and I can't believe Microsoft hasn't gotten around to this yet). However, Boolean type data is usually a DWORD (4 byte) or String (2 byte) item type in the registry. If you're using your .reg file to change values, check the data item in the registry to make sure you match the data type. You don't need to enter the full string in your .reg file; you can omit leading zeros for all numeric values.
Figure 1 shows a sample .reg file that you can use to get rid of the Start menu's Documents item. (You probably won't find many users who miss the Documents menu item or even notice that it's gone. If a user wants to keep the Documents menu, don't send the file to that person.)
Distributing Registration Files
A quick way to create a .reg file for distribution is to use regedit to export a key (or multiple keys), then use the resulting .reg file (or files). To export a key, select the key and choose Registry, Export Registry File. In the Export Registry File dialog box, enter a name and select a folder for the export file. Windows automatically adds the .reg extension. You can interactively change the registry settings on one computer, then export the key and use the export file as is, or you can export the key, then manually edit it. To edit a .reg file, don't double-click the file; instead, right-click and choose Edit from the shortcut menu. The file opens in Notepad. If you want to make registry changes in multiple keys, open each .reg file, paste the files' contents into one Notepad document, then save that document with a .reg extension.
You can distribute .reg files in any convenient manner. Attach the .reg file to an email message, add the appropriate command to a logon script, or use any other method you're comfortable with.
Users don't need to open regedit and use its Import command to bring the contents of a .reg file into the registry; they can merely double-click the .reg file from Windows Explorer or My Computer to automate the import process. (If you right-click a .reg file, you can see that the default action is Merge. However, no Merge command exists in any version of Windows; that command is a stand-in for the command
in which the variable uses the current file.) For command-line execution, use the syntax
Regardless of the method, the OS asks the user to confirm that he or she wants to merge data into the registry. Clicking Yes launches the merge. After the file successfully merges into the registry, the OS issues a success message. If the file has the wrong syntax and the merge fails, the OS issues an error message explaining that the file isn't a registry script and can't be imported to the registry.
If you want to execute multiple .reg files (one for each modification) instead of combining all the registry changes into one file, use a batch file that calls each .reg file. To avoid the need for user intervention, use the following syntax to run .reg files from the command line in quiet mode:
regedit /s <filename>.reg
Registration files work for Win95 and later. However, many registry subkeys and data items differ among versions, so you should create separate .reg files for each platform. Name the files appropriately so that you don't get confused (e.g., RestrictUsers9x.reg, RestrictUsersNT4.reg).
Note that even if you've used Group Policy or System Policy to disable registry-editing tools, .reg files still work. (Otherwise, software installation and other system processes couldn't manipulate the registry.)
Option 2: Get More Editing Power with Regini.exe
If scripts are your favorite tools for configuration and setup tasks, you can use regini.exe to apply your scripting skills to registry edits. Regini provides more power than .reg files can muster, including the ability to delete subkeys and data items and to set permissions on registry keys. You can find Regini in the Microsoft Windows 2000 Server Resource Kit and the Microsoft Windows NT Server 4.0 Resource Kit. (I've successfully used the Win2K version of regini.exe on NT machines, and vice versa.) The resource kits also contain full documentation (i.e., regini.doc) for this nifty utility. Regini uses the following syntax:
where ScriptFileName is the path to a script file you've written to perform a specific registry edit. You can use Uniform Naming Convention (UNC) in the path statement if the script is on a network share.
To distribute registry changes that use Regini, you must make the program available to each target computer (assuming that you haven't installed the resource kits across your enterprise). You can use a batch file to map Regini's UNC path and then run the program. For example, if Regini resides on a network share named ResKit on a server named Tools1, you can create the following batch file:
Net use x: \\tools1\reskit x:\ regini <ScriptFileName> Net use x: /delete
Script File Guidelines
The script file you use with Regini can have any name and extension you want. The file must be in ANSI format; regini.exe converts the file to Unicode when it reads the file, but you can't use a Unicode text file as the script file. (Microsoft should fix this limitation.) Registry commands in this script file must use the following syntax:
\Registry\<KeyPath> \[<ACL>\] <DataItemName> = <DataType> <DataValue>
The presence of an equal sign in a line indicates that the line contains a registry data item and a value that you're adding, deleting, or modifying.
Lines in the script must have a carriage return at the end. If a line wraps, which usually happens when the registry key is deeply nested and therefore very long, the continuation symbol is a backslash. So, if you enter
regini.exe reads the line as SomethingMorestuff Evenmore. Note that the space before the backslash on the second line inserts a space between Morestuff and Evenmore. If no space is required (i.e., if the point at which the wrapping occurs isn't a natural space such as the space within the name of a subkey), omit the space before the backslash.
The first line of each registry command contains the KeyPath variable, which is the full path to the key you're manipulating. If the key doesn't exist in the registry when you run the script, the command will add it. Regini.exe uses the kernel naming conventions for registry subtrees, and you can either enter kernel names in your script or use standard subtree names and let regini.exe translate them. (The kernel conventions are easier to type.) The kernel naming conventions for subtrees are as follows:
- HKEY_LOCAL_MACHINE is \Registry\Machine
- HKEY_USERS is \Registry\User
- HKEY_CURRENT_USER is \Registry\User\User_SID
The first line can also contain an optional ACL variable. You can include this variable to manipulate ACL permissions instead of, or in addition to, keys and data items. The ACL data comes after the KeyPath variable and consists of a series of numbers separated by spaces and enclosed within square brackets. (Table 2 lists these numbers and their meanings.) For example, the following command:
\Registry\machine\system\currentcontrolset \[1 11 17\]
assigns Administrators Full Access, Power Users Full Access, and System Full Access permissions to the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet registry subkey.
Watch out: This feature is dangerous if you don't understand the way it works. When you use this feature, you aren't adding the ACL permissions that you enclose within the brackets—you're resetting the ACLs. The data within the brackets replaces any existing data. Don't use this feature unless you first check the existing ACL for the key you're manipulating. (You can use regedt32 to view the ACL.) Otherwise, you might accidentally eliminate or modify permissions for a group.
The second line contains the information for the data item you're manipulating: DataItemName is the name of the data item and consists of every character from the first nonblank character on the line to the last nonblank character before the equal sign. You don't need to use a special format (e.g., enclosing the name in quotation marks) to handle data items with spaces. If the data item doesn't exist in the registry when you run the script, the command will add it.
DataType is the data type for the data item. Regini recognizes the text to the right of the equal sign, up to the first space, as the data type.
DataValue represents the value you're applying to the data item. This value begins with the first nonblank character following the space after the data type and continues to the end of the line. You don't need to use any special handling to specify spaces within a value.
Regini.exe expects the data type and its accompanying value in your script to match certain standards. These standards are as follows:
- REG_SZ or REG_EXPAND_SZ for string values.
- REG_MULTI_SZ for multiple strings. You must surround each string with quotation marks.
- REG_DWORD for decimal or hex values. For REG_DWORD data items, the default value is decimal. Use 0x to specify a hex value. If you enter the value On, True, or Yes, the value is converted to 0x00000001; if you enter the value No, False, or Off, the value is converted to 0x00000000.
- REG_BINARY for binary values formatted as two or more decimal numbers. The first decimal number specifies the number of bytes of data that follow. The remaining numbers are converted into 32-bit numbers. (The value length must always be a multiple of 4 bytes.)
Regini gives you several options for data manipulation. For example, DELETE is a regini.exe keyword that requires only the name of the data item. To remove a data item, enter the following syntax as the second (i.e., data item) line of your script:
DataItemName = DELETE
Regini.exe also has a neat feature that lets you point to a text file that contains the value for a data item. This feature eliminates the need to directly enter long binary values (for REG_BINARY data items) or many multiple strings (for REG_ MULTI_SZ data items). During execution, regini.exe opens the target file and writes its contents to the registry as the value for the data item. To use this feature, replace the item type with an instruction to use a file. The instruction includes a reference to the item type and uses the following syntax options:
- For REG_BINARY data items: DataItemName = REG_BINARYFILE FilePath
- For REG_MULTI_SZ data items: DataItemName = REG_MULTISZFILE FilePath
For example, if you enter the following script:
UserNicknamesForCompanyNewsletter = REG_MULTISZFILE \myscripts\script101.txt
Regini reads the content of the file named script101.txt and writes the contents as the value of the data item UserNicknamesForCompanyNewsletter. (I made up that data item for this example, so don't look for it in your registry.)
Putting It All Together
As an example of a complete command, review the following script. This command changes computer settings so that the most recent user's name doesn't appear in the Logon dialog box.
\registry\machine\software\micro soft\windows\currentversionpolicies\system DontDisplayLastUserName = REG_DWORD 1
To make additional changes in the same subkey, you need only add lines below the line that references the subkey. As long as each additional line contains an equal sign, regini.exe properly handles the line's content. For example, the data items that control pre-logon messages (i.e., LegalNoticeText and LegalNoticeCaption) reside in the same registry subkey as the DontDisplayLastUserName item. To also configure the computer to display a message before users log on, simply add two lines to the previous script:
\registry\machine\software\micro soft\windows\currentversionpolicies\system DontDisplayLastUserName = REG_DWORD 1 LegalNoticeText = REG_SZ Your E-Mail is Now Being Monitored LegalNoticeCaption = REG_SZ Notice To Employees
Option 3: Use Policies
You can also distribute registry changes by creating system policies that manipulate the registries of target users. The process you use varies between Win2K (which uses the Microsoft Management Console—MMC—GPE snap-in) and earlier versions of Windows (which use SPE), but in either case, you can build administration (.adm) files to send registry changes to selected computers.
The easiest way to create an .adm file is to use an existing .adm template as a starting point. Templates are text files, and you can open them in Notepad or any text editor. Before you do anything with existing templates, back up the originals. When you modify a template, save the new version with a new filename, even if you've backed up the original. And you must test your new .adm files in a lab environment before you unleash your creation on the enterprise. (See Reader to Reader, ".adm Files and the Headaches They Can Cause," October 1999, for a description of the consequences you might face if you ignore this advice.)
Of course, to implement a registry change through an .adm template, you need to know which registry key to target. The resource kits' registry documentation is rather sparse. To learn my way around the registry, I used a lab environment to plunge in and make system changes with existing policies and Control Panel applets. I used Sysinternals' regmon.exe (available from http://www.sysinternals.com) to track the resulting registry changes. Eventually, I learned quite a bit about the registry's organization and registry entries' data types.
Creating .adm Files for the Win2K GPE
Win2K's GPE snap-in offers hundreds of policies. (SPE offers less than 100 policies.) Figure 2 shows the available scope of policy categories.
Only the policies available under the Administrative Templates nodes are direct registry entries; you can view or modify these templates as a basis for registry changes. The available policies cover almost every user setting or preference you can think of, so you aren't likely to need to create your own templates. But you might discover a registry setting that the templates don't already cover, or you might want to impose settings specific to user controls for inhouse software. Another reason to create your own template is to combine existing registry changes from the existing templates. You can then use this combo template to apply commonly invoked changes to specific groups of computers or users.
The relationship between the GPE snap-in and its templates is similar to the relationship between SPE and its templates. Figure 3 shows the policies for User Configuration\Administrative Templates\System. For the policy named Don't display welcome screen at logon, the following code is in the System.adm template:
POLICY !!NoWelcomeTips KEYNAME "Software\Microsoft\ Windows\CurrentVersion\Policies\Explorer" EXPLAIN !!NoWelcomeTips_Help VALUENAME "NoWelcomeScreen" END POLICY
In a GPE template, the POLICY section includes the registry key, even if the registry key is the same as the preceding or following policy. Note the two exclamation points to the left of the policy name; these marks identify a variable. The \[Strings\] section for this example includes the following code, which matches the text in the GPE snap-in:
NoWelcomeTips="Don't display welcome screen at logon"
EXPLAIN, which doesn't exist in SPE templates, also has two exclamation points as the first characters of its value, identifying a variable in the \[Strings\] section. Note that the string name is the same as the string name for the policy name, with the addition of an underscore and the word Help. In this case, the variable points to the text that appears on the Explain tab.
In the \[Strings\] section of System.adm, we find the variables that Figure 4, page 76, shows. The \n within the text inserts a carriage return. If you're creating policies, you don't need to write explainers. The system won't complain if you omit them.
Creating .adm Files for the NT or Win9x SPE
NT and Win9x implement ADM templates into SPE (i.e., poledit.exe). You must use the appropriate platform version of SPE to implement the policies you create in your .adm file. (For an example of how SPE and an .adm template correspond, see the sidebar "Make the Connection.") NT Server includes three templates:
- Common.adm—registry settings common to both NT and Win9x
- Winnt.adm—registry settings specific to NT
- Windows.adm—registry settings specific to Win95
You can modify these templates, which reside in \%systemroot%\inf. For example, you can edit the templates to remove options you never want to implement—an important ability if assistants in your IT department use SPE. You can also add options that the standard template files don't include. Templates have the following limitations:
- Policies are limited to the settings available in the HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER registry subkeys.
- You can't reference a registry key that requires binary data.
You can also create templates and save them in the \%systemroot%\inf folder. To use the templates, open SPE; choose Options, Policy Template from the menu bar; and select your file.
A template's syntax uses keywords that are linked to variables; the variables reference registry keys. A template with one option would use the following syntax:
CLASS CATEGORY KEYNAME POLICY PART VALUENAME "value" VALUEON VALUEOFF END PART END POLICY END CATEGORY \[Strings\]
CLASS names the registry section (i.e., MACHINE for HKEY_LOCAL_MACHINE or USER for HKEY_CURRENT_USER). Every template has either one or two CLASS indicators. You must group all the policies for one CLASS before you take on the second CLASS (if you're using two classes). Template files don't include an END CLASS line; instead, the naming of a new CLASS specifies the end of the previous CLASS. The beginning of the \[Strings\] section marks the end of the second CLASS.
CATEGORY defines the beginning of a category (and becomes a book icon in the SPE window's display); END CATEGORY defines the category's end. A category is a group of policies with a logical connection, all of which appear as a heading that you can expand in the SPE window. You can nest categories. The CATEGORY command uses a variable that represents a text string, delineated in the \[Strings\] section of the template. The text string appears in the SPE window as the definition of the policy.
KEYNAME is the registry key that holds the entry for the policy. If the key doesn't already exist, KEYNAME will be a new registry key that will hold the entry. If the registry path to the key contains spaces, enclose the entire key path (excluding HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER) in quotation marks.
POLICY is the policy setting. The setting must exist within a CATEGORY, and its name describes its function. A POLICY is accompanied by a three-state check box that appears in the SPE window so that you can specify whether to enable, disable, or ignore the policy. END POLICY specifies the end of the policy.
PART signals the beginning of a part within a policy (policies can have multiple parts). END PART signals the end of a part. PART is used for more complicated policies that need to establish additional values in the Settings box at the bottom of the SPE window. By additional values, I mean that the policy requires more options than enable or disable. If you're setting a wallpaper policy or a screen saver policy, you need to enter the name of the appropriate file. You can also use PART to display explanatory text in the Settings box.
VALUENAME is the name of the registry entry (i.e., subkey or data item) that you're modifying or creating. If the VALUENAME entry in the registry has any spaces, enclose the name in quotation marks.
VALUE is the value you want to assign to the registry entry defined by VALUE NAME. VALUE can be text (which you must enclose in quotation marks) or numeric.
VALUEON and VALUEOFF are used for operating SPE in Registry Mode, when the VALUENAME requires nothing more than a check box to enable or disable the policy. Usually, you use the common enable and disable values in the registry: 1 for on or 0 for off.
\[Strings\] is the final section of the template and lists the variables for the template. Microsoft uses the word "variable," but these are actually the sentences that appear in the SPE window and that describe the policy. Within the template, any entry that's prefaced by two exclamation points specifies a variable that will appear in the \[Strings\] section. The following lines are part of the \[Strings\] section in Common.adm. The variable is to the left of the equal sign, and the contents of the variable, enclosed in quotation marks, are to the right of the equal sign.
RemoveRun="Remove Run command from Start menu" RemoveFolders="Remove folders from Settings on Start menu" RemoveTaskbar="Remove Taskbar from Settings on Start menu" RemoveFind="Remove Find command from Start menu"
Your OS automatically distributes system and group policies. (For information about Group Policy distribution, see Randy Franklin Smith, "Controlling Group Policy, Part 2," Winter 2000.)
The discussions in this article are for administrators who understand the registry well enough to manipulate it without causing destruction or chaos. Although you have a variety of tools for maintaining the registries of your network's computers, approach registry tasks with care. Back up any registry key before you change its contents. Spend a lot of time working with large-scale registry management tasks in a lab environment before you attempt any tasks in the enterprise. And if the registry baffles you—don't mess with it.