Reading IIS settings with ADSI Scripts
Web site administrators who manage many IIS boxes have repeatedly told me that administering IIS with scripts seems like the way to go. However, finding the time to churn through the documentation stops many administrators. Microsoft has done a good job providing sophisticated scripts to manage IIS and has provided documentation that contains powerful script samples. However, simple script samples accompanied by straightforward applied discussions are hard to find. I hope to fill this void and demonstrate the ease with which you can write scripts for IIS administration.
Administering IIS typically involves reading and configuring settings and performing important tasks, such as nightly IIS backups. You can use scripts to read and write IIS settings and perform just about any task that the IIS console supports. In this article, I explain how to access and read IIS settings. In later articles, I'll explore how to write IIS settings and perform tasks.
IIS and the Metabase
Reading IIS settings is useful to Web administrators for many reasons. For example, you can read IIS settings to determine a Web server's configuration, verify changes after reconfiguring a Web server, and compare two Web servers' IIS configuration settings. Instead of using the registry for the majority of its configuration settings, IIS uses a special data store called the metabase. The metabase loads into memory when IIS starts. The metabase's structure and location in memory make it a high-performance and flexible data repository for IIS configuration data.
The metabase is a hierarchical data structure that consists of keys (aka nodes or objects). Keys are to the metabase as folders are to the file system. Each key contains configuration data specific to that key. The configuration settings are attributes of the key.
The Computer key is the root of the IIS hierarchy. This key contains global configuration settings that determine how IIS operates. Under the Computer key are trees for each service installed in IIS. For example, an IIS computer that supports Web sites, FTP sites, and SMTP virtual servers has trees for Web services (W3SVC), FTP services (MSFTPSVC), and SMTP services (SMTPSVC). Below these keys are instances of each service. Each instance is represented by a numeric value, starting from 1. For example, the Default Web site is instance 1 and the Administration Web site is instance 2. These two sites are contained below the Web server. Figure 1 shows part of a sample metabase hierarchy. For brevity, Figure 1 shows only one Web site (i.e., instance 1).
To permit inheritance, the metabase is hierarchical. For example, if you disable the Enable Default Document attribute at the master properties level of the Web service, this setting flows to the Web site child nodes, which also contain the Enable Default Document attribute. The master properties level is the top of the Web service hierarchy in the IIS console. All the Web sites on the computer inherit any configuration at the master properties level, unless the setting is specifically configured on a child node.
Reading the Metabase Keys
To read metabase keys and perform other Web server scripting tasks, you can use Microsoft Active Directory Service Interfaces (ADSI) and the IIS Admin Objects. This approach works well on IIS 6.0, IIS 5.1, and IIS 5.0. Although you can use ADSI with IIS 4.0, I've never tried it. I've tested the sample scripts in this article on IIS 6.0, IIS 5.1, and IIS 5.0 only.
ADSI is a set of COM objects that make providers and automation interfaces (i.e., objects) available. Providers are components that access directories. For example, the ADSI IIS provider is a component that accesses the IIS metabase. The core interfaces in ADSI apply to all kinds of directories, including the metabase. Through interfaces, ADSI provides properties and methods to expose a directory's configuration settings. A property is like an adjective; it describes an aspect of an object. A method is like a verb; it lets you take action with an object.
IIS Admin Objects are additional ADSI COM objects specifically designed to provide key-specific automation interfaces to the metabase. In Figure 1, the second line of each key shows the name of the interface for that key. For example, the Computer key's interface is named IISComputer, which is the metabase's root interface. Like the interfaces in ADSI, the interfaces in IIS Admin Objects contain properties and methods. For example, the IISComputer interface includes the MaxBandWidth and MimeMap properties, which let you view bandwidth and mimemap settings, respectively. This interface also contains methods, such as the Backup and Restore methods, which let you perform backup and restore procedures, respectively.
With ADSI and IIS Admin Objects, you can use a scripting language such as VBScript to read and configure metabase keys. Just as when you work with the registry, when you work with the metabase, you need to exercise caution because making an inappropriate change can cause IIS failures. Using a script to read a metabase key typically involves two steps:
- Connect to a metabase key. This step is known as binding to the metabase. In a metabase bind operation, ADSI reads the key and creates a virtual object representation of that key in the local computer's memory. For example, look at the script IISAtt_ReadComputer.vbs, which Listing 1 shows. In the first line of code, the bind operation uses the GetObject function with a path called the ADsPath. Notice that I used a Fully Qualified Domain Name (FQDN) in the ADsPath, which points to an IIS server named sea-dc-01.fabrikam.com. An FQDN is the entire domain name for a specific computer on the Internet or an intranet. However, you can also use the computer's localhost (assuming that you run the script on the local IIS server) or NetBIOS name in the ADsPath. These three types of identifiers appear at the top of Figure 1 in the box labeled Computer. I recommend that you use the localhost rather than the FQDN if you want the script to return values from local IIS computers. This approach makes the script work properly on all IIS computers without having to modify the identifier in the ADsPath.
- Read the attributes. Initiating a read operation downloads the metabase key's attributes to the local property cache. To read these attributes, IISAtt_ReadComputer.vbs uses ADSI and IIS Admin Object interfaces. The code at callout A in Listing 1 uses ADSI's core interface, IADs, to display the six standard properties that are present in all ADSI objects: Name, ADsPath, Class, GUID, Parent, and Schema. The code at callout B in Listing 1 uses the IISComputer interface to display two properties: MaxBandWidth and MaxBandWidthBlocked. The values of these two properties are easy to read because they're integers. However, not all property values are integers. For example, the MimeMap property value is a collection object that represents a list of filename extensions for MIME mappings (e.g., the .xsd extension has a MIME type of text/xml). MimeMap is a property of the IIsMimeMap object, an IIS Admin Object. As the script IISAtt_ReadMimeMap.vbs in Web Listing 1 (http://www.windowswebsolutions.com, InstantDoc ID 26261) shows, to read the IIsMimeMap object, you first bind the corresponding metabase key, then use the IADs interface's GetEx method to retrieve the collection. In this case, the collection contains two properties: MimeType and Extension. A For Each...Next statement then displays each MIME type and its associated extension.
To determine the data types of IIS properties, you can go to the Alphabetical Property List Web page in the Microsoft Developer Network (MSDN) Library (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/iisref/html/psdk/asp/apro1cms.asp). Another option is to create a script that reads data types. The script IISAtt_ReadAll.vbs, which Web Listing 2 (http://www.windowswebsolutions.com, InstantDoc ID 26261) shows, is an example of that type of script.
Making Metabase Reading More Flexible
IISAtt_ReadComputer.vbs and IISAtt_ReadMimeMap.vbs are intentionally simple to help you grasp how to read properties of ADSI and IIS Admin Object interfaces. However, the keys' attributes vary, as do the properties of the IIS Admin Object interfaces that read the keys. Therefore, hard-coding property names into scripts is a tedious approach to reading attributes from the metabase.
Thankfully, ADSI includes three schema interfaces—IADsClass, IADsProperty, and IADsSyntax—that let you determine all the attributes in a particular key and gather other useful information, such as each attribute's data type. Knowing the data type lets you determine how to perform read operations. As IISAtt_ReadComputer.vbs and IISAtt_ReadMimeMap.vbs demonstrate, the code to read attributes stored as integers differs from the code to read attributes stored as objects.
Describing the various interfaces for reading attribute definitions gets a bit complicated. If you study IISAtt_ReadAll.vbs before reading the next section, you'll find the discussion easier to understand. All you need to keep in mind is that the schema interfaces let you read and differentiate between the various attributes in the metabase.
Reading Attribute Definitions
IISAtt_ReadAll.vbs uses the IADsClass interface and several properties to return information about the attributes contained in a metabase key. In a nutshell, the script reads the metabase key that corresponds to the IIS Admin Object's name, which the objKey object variable refers to. The WScript.Echo and WScript.StdOut.Write commands then display the interface properties and values of the IIS Admin Objects.
Now let's take a closer look at IISAtt_ReadAll.vbs. The first line of code includes an identifier that points to an IIS server named sea-dc-01.fabrikam.com. If you use IISAtt_ReadAll.vbs, you need to change this identifier to one that points to your IIS server. Next, the script sets the strKey variable to W3SVC/1, which is the metabase key that represents the IISWebServer interface of the first Web site. Below the strKey variable, I've included some additional sample keys that represent various IIS Admin Objects. You can try these strings and refer to Figure 1 if you aren't sure of the proper metabase path. If you didn't specify a key and strKey is empty, the script sets the objKey object variable to the IISComputer interface because that's what the strADsPath points to. Otherwise, the script appends the metabase key to strADsPath to create the appropriate IIS Admin Object interface.
The code at callout A in Web Listing 2 is similar to the code in Listing 1. The code returns the values of the standard IADs properties for the specified object.
The code at callout B in Web Listing 2 shows how to use properties of the IADsClass interface to retrieve the name of each metabase attribute in the specified key and determine each attribute's data type. The IADsClass interface's OptionalProperties property retrieves the names of the attributes. Although the IADsClass interface has a MandatoryProperties property, all attributes in the metabase are defined as optional because the ADSI IIS provider doesn't require mandatory properties.
After the script has all the attributes' names, the script uses the IADsContainer and IADsProperty interfaces to determine each attribute's data type. Using the values returned by these two interfaces and the IADsSyntax interface, the script determines the OLEAutoDataType property of each attribute. The OLEAutoDataType property returns an integer that represents the enumeration of the automation data-type constants. The script uses this enumeration to categorize the various IIS data types. For example, MimeMap (data type: MimeMapList), AdminACL (data type: NTAcl), and IPSecurity (data type: IPSec) all have an OLEAutoDataType value of 12. Most important, if the OLEAutoDataType property value is 12 but isn't a List data type, the attribute returned is an automation data type that needs to be read differently than the other attributes.
Although a List data type has an OLEAutoDataType value of 12, you can read it in the same fashion as attributes that don't have an OLEAutoDataType of 12 because the List data type is a 1-D array that contains zero or more values. You can think of a 1-D array as a table that contains one column. In contrast, the MimeMapList data type is a 2-D array that contains zero or more values. For example, MimeMap, which is a MimeMapList data type, has two dimensions: MimeType and Extension.
The code at callout C in Web Listing 2 shows how an attribute's value is read if its OLEAutoDataType property isn't 12 or if the data type is List. Later in callout C, the script checks for attributes whose OLEAutoDataType property is 12 and whose data type isn't List. If that situation occurs, the script displays the attribute's name and data type. The script ends with a demonstration of how to iterate through the MimeMapList collection.
IISAtt_ReadAll.vbs only displays the data types of the AdminACL, IPSecurity, and SSLCertHash objects. In a later article, I'll demonstrate how to read the attributes of these objects.
Because IISAtt_ReadAll.vbs uses the WScript.StdOut.Write method, you must run this script from the command line. If CScript isn't your default scripting host, you can type
from a command prompt to run the script at the console. If you want to redirect the script's output to a text file, type
where iis.txt is the name of the file to which you want to redirect the output.
It's as Simple as That
Thanks to ADSI and the IIS Admin Objects, reading the metabase involves just two steps: binding to the appropriate metabase key, then using the appropriate ADSI and IIS Admin Object interfaces to read the key's attributes. You can even use the ADSI schema interfaces to reduce the tedium of defining each attribute in the script. After you know how to access and read the metabase from a script, you're well on your way to administering IIS.