Executive Summary:

The Department of Defense (DoD) establishes strict security guidelines and standards that all DoD agencies must follow in their networks. Sometimes the requirements can seem daunting. For example, Windows desktops must be configured to treat 48 different file types with care. To make the registry settings needed to comply with established requirements for these file types, Rick Bridges wrote a VBScript script that uses the Microsoft Scripting Runtime Library's Dictionary object and Windows Management Instrumentation's (WMI's) StdRegProv class. As Rick learned, scripts can make seemingly daunting requirements easy to meet.

As anyone who has worked on a Department of Defense (DoD) network will tell you, security in those environments is paramount. There are strict security guidelines and standards that all DoD agencies must follow. If you don’t follow the rules, the DoD can and probably will pull the plug on your network. Although the requirements improve network security, meeting them can be challenging because sometimes they're set with little or no guidance on how to achieve compliance. By no means is this an indictment of the DoD security guidelines and standards; they simply set the course and establish direction. Once the need to get from point A to point B is established, the mode of transportation utilized is of little concern.

Case in point: Windows desktops must be configured to treat specific file types with care. For example, when a user double-clicks a .vbs file, Windows must open the file in Notepad for editing rather than run the script with Windows Script Host (WSH). VBScript isn't the only file type that needs to meet this requirement. In all, 11 types of code files must be configured to open in edit mode in Notepad by default.

In addition, the following requirements have been established for 48 file types:

  • Filenames must always include the file extension.
  • When users download a file, they must be prompted with a dialog box that allows them to open the file, save the file, or cancel the operation.

So, how does one meet these requirements? I determined that using a custom administrative template in Group Policy wouldn't work well in our environment because the same set of software isn’t installed on every workstation. I also determined that a third-party utility probably wouldn't be smart enough to update the correct registry entries for different software versions or replace registry entries modified later by software installs or updates.

I needed a solution that would regularly run through the list of 48 files types to determine which file types are registered on a given system and, when applicable, modify the associated registry settings for those file types. Thus, I wrote the FileTypes.vbs script, which Listing 1 shows. This startup script is applied through a Group Policy Object (GPO) that's linked to an organizational unit (OU) containing the target workstations. Because this startup script runs after every reboot, it's a hassle-free way to ensure compliance.

Listing 1 shows FileTypes.vbs. The script begins by declaring a constant and several variables. The HKLM constant and strClasses variable will be used to build the path to the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Classes, which contains the registry entries that must be changed. Those entries include AlwaysShowExt, which is used to enable the Always show extension setting, and EditFlags, which is used to enable the Confirm open after download setting. The strCommand variable holds the command that will be used to open the 11 types of code files in Notepad by default.

Next, the script creates a Dictionary object to store the file extensions and some values used to flag the file types that execute code. For each key-item pair, the key is the file extension and the item is either a value of 1 (indicates that the file type executes code) or a value of 2 (indicates that the file type doesn't execute code). When the dictionary item's value is 1, the script will change the default mode for that file type from "Open" to "Edit".

Before populating the dictionary, though, the script sets the dictionary's CompareMode property to 1. By default, this property has a value of 0, which means the dictionary makes binary comparisons. When you set the property to 1, the dictionary makes textual comparisons. You must set the CompareMode property when the dictionary is empty. Otherwise, an error will occur.

In the code at callout A, the script uses Windows Management Instrumentation's (WMI's) StdRegProv class to bind to the registry. Once that connection is established, the script iterates through the dictionary. For each key-item pair, the script executes the FileTypeMgmt subroutine, which modifies the registry settings associated with the file type.

The FileTypeMgmt subroutine first builds the path to the file type's registry entry using the HKLM constant, the strClasses variable, and the file extension in the dictionary key. Using the StdRegProv class's GetStringValue method, the subroutine retrieves the data from that registry entry and stores it in the strValue variable. When strValue contains data, the subroutine uses the StdRegProv class's SetStringValue method to enable the AlwaysShowExt setting and the class's SetDWORDValue method to enable the EditFlags setting.

Next, the FileTypeMgmt subroutine checks to see whether the dictionary item's value is 1. If so, the subroutine makes the necessary registry modifications so that the code files of that type open in edit mode in Notepad. When I was writing this part of the subroutine, I ran into a problem when trying to retrieve the value of the (Default) entry, which specifies the mode. When you use the GetStringValue method to retrieve a string value in a registry entry, you typically specify four arguments: the hive, the registry path, the entry's name, and the name of the variable that will hold the retrieved value. However, when I specified (Default) as the entry's name, it didn’t work. I quickly realized that if you want to retrieve the value assigned to the (Default) entry, you must leave the entry's name blank. For example, the code

objReg.GetStringValue HKLM, _                                strFTE, , strValue                              If IsNull(strValue) = False Then

retrieves the value for the (Default) entry, which is used to verify whether a registry entry for the file extension exists. I applied the same technique when I used the SetStringValue method to write a new value in the (Default) entry. For example, the code

objReg.SetStringValue HKLM, _                                strFT &  "\Shell", , "Edit"

sets the (Default) entry's value to "Edit".

When I initially read the DoD requirements, they seemed a little daunting. However, as FileTypes.vbs demonstrates, those requirements can be easily met with a simple startup script.

—Rick Bridges, Systems Administrator, IntelliDyne

Share Your Scripting Experiences
