Most Microsoft IIS administrators face numerous repetitive tasks: Creating sites, creating virtual directories, searching for a particular setting, determining security compliance—to name just a few. Using GUIs to complete these tasks over and over is tedious and time-consuming. Scripting such tasks is a faster and more powerful method, and IIS provides many easy-to-learn scripting interfaces. By customizing the scripts that accompany this article, you can retrieve, create, and modify IIS configuration data. The sample scripts use Active Directory Service Interfaces (ADSI) and JScript and work on IIS 4.0 and later. Of course, you must run all these administrative scripts under the security context of a user who has administrative rights on the target machine.
Your First Script
Your first task in learning IIS administrative scripting is to configure your server so that your scripts' results will be output as text in the command-shell window rather than as graphical message boxes. To do so, open a command shell on the IIS server and type
To test this configuration, let's create a simple JScript script that returns the path to your default Web site. Open Notepad or another text editor and enter the following code on one line:
WScript.Echo ("Physical path of my default web-site: " + GetObject ("IIS://localhost/W3SVC/1/ROOT").Path);
Save the file as iispath.js. Go back to the command shell and type
This command runs the script. If you configured the server properly, you'll see output similar to the output that Figure 1, page 56, shows. This output shows the physical path of your default IIS Web site. Congratulations—you've written your first IIS script. Now, let's move on to bigger and better things.
The Metabase: Home of IIS Configuration
To use scripts to manage IIS, you need to know something about IIS's configuration store: the metabase. The metabase, which is similar to the registry, is a hierarchical data store that provides configuration data for IIS and its services (i.e., the World Wide Web Publishing Service—W3SVC, FTP, SMTP, Network News Transport Protocol—NNTP, IMAP, and POP3). The most popular way to view the metabase's configuration data is by using the Microsoft Management Console (MMC) Internet Information Services (IIS) Manager snap-in. This snap-in provides an easy-to-use management GUI that presents a simplified view of the metabase's hierarchy and structure. But to access the power of administrative IIS scripting, you need to look at the metabase in more detail than the GUI provides.
The IIS 6.0 metabase is a plain-text XML file, so you can view the metabase by opening metabase.xml (under %windir%\system32\inetsrv) in Microsoft Internet Explorer (IE). To modify IIS configuration, you can directly edit the .xml file. To do so, open a command line and type
net stop iisadmin /y
to stop the IISAdmin service. Then, type
to open the metabase in Notepad. Select Edit, Find from the menu bar and search for the string ServerComment. This search will return the entry ServerComment="Default Web Site". Change this entry to something such as ServerComment="My IIS 6.0 Site" and save the file. Open the IIS Manager snap-in (doing so automatically starts the IISAdmin service) and navigate to the Web Sites node. You'll see that your default Web site is now named My IIS 6.0 Site. (To edit IIS configuration without stopping and restarting the IISAdmin service, you can use IIS 6.0's Direct Metabase Edit feature; see "Related Reading" for more information.)
The IIS 5.1, IIS 5.0, and IIS 4.0 metabases, however, are binary files, so you don't have the luxury of simply reading the metabase in a browser. Instead, you can use IIS Metabase Explorer, a brand-new tool available in the Microsoft Internet Information Services (IIS) 6.0 Resource Kit—provided that your Web server also runs the Windows .NET Framework. For IIS 5.0 and later, Metabase Explorer also presents a more in-depth graphical view of the metabase than the IIS Manager snap-in provides. Metabase Explorer doesn't work with IIS 4.0, however, so for IIS 4.0 you need to use MetaEdit 2.2. (See "Related Reading" for information about downloading Metabase Explorer and MetaEdit.)
As you begin to delve into the metabase, the first thing you encounter is its hierarchical nature. Most tasks you want to accomplish with a script involve setting or retrieving a property at a specific node in the hierarchy. Be certain to keep this hierarchy in mind when writing scripts, or you might unintentionally change child elements' properties.
Let's use Metabase Explorer to accomplish the same task as iispath.js—locating your default Web site's path. To do so, we'll explore the pathname (i.e., IIS://localhost/W3SVC/1/ROOT) that we used in iispath.js. Expand the Web server object, then expand the LM (LM stands for local machine, represented by localhost in iispath.js's pathname argument), W3SVC, 1, and ROOT nodes. When you select the ROOT node, the right-hand pane displays several properties. The Path property appears in the right-hand pane, as Figure 2 shows.
Now, let's change iispath.js so that its results display some of the other properties you see in Metabase Explorer. For example, to output the default documents, modify the one-line script to read as follows:
WScript.Echo ("Default Documents: " + GetObject ("IIS://localhost/W3SVC/1/ROOT") .DefaultDoc);
Notice that both versions of iispath.js use the JScript GetObject function to retrieve IIS configuration data. This function accesses an object of a specific class (aka Key Type), depending on the pathname argument you use. (When you use Metabase Explorer to view an object's properties, the object's class appears as the KeyType.) Table 1 shows some examples of the classes that the GetObject function can access. (The IIS documentation describes the properties and methods that each class supports, these properties' functions, and how to change the properties.) After you access an object derived from one of these classes, you can query the object as to its properties so that you can determine specific settings, such as a virtual directory's path or a Web site's IP address. You can use scripts to set values for these settings or, in some cases, invoke predefined actions, called methods (e.g., the Backup method, which backs up the metabase). Let's examine the objects at each level of the hierarchy in our example pathname.
The machine node (IIsComputer class). Providing the IIS://localhost pathname as an argument to the GetObject function causes the script to return an object with the class IIsComputer; the object represents the machine node. This class has only a few properties and machine-specific methods, such as the Backup and Restore methods.
Listing 1 shows a sample script that uses the Backup method to back up the IIS metabase. After you run this script, the file MyBackup.md0 will appear in the system's %windir%\system32\inetsrv\metaback directory. The backup function lets you specify a backup-version number. If you don't want to bother with this specification, you can set the number to -1, as the code at callout A in Listing 1 shows, and IIS will automatically select the next available version number.
Listing 2 shows a sample script that uses the Restore method to restore the backup. The code at callout A in Listing 2 tells IIS to use the highest existing backup version. If you want to restore a particular backup version, you can replace "-2" with a specific version number (e.g., "100"). To verify that your scripts' backup and restore functionality is working, invoke the backup script, delete a test virtual directory, then invoke the restore script and verify that the deleted virtual directory is restored.
The IIsComputer class is also the entry point to remote management of one or more IIS machines. Instead of using localhost in the pathname when calling the IIsComputer object, simply reference the remote system's machine name (e.g., iisgeekserver) or IP address. This remote-management functionality occurs through Distributed COM (DCOM). If different credentials are necessary to connect to the remote machine, you must use the ADSI IADsOpenDSObject core interface's OpenDSObject method instead of the GetObject function. The script that Listing 3 shows first uses the GetObject function to access the IIS ADSI provider, then calls the OpenDSObject method, passing the necessary username and password for authentication on the remote system. (For more information about the ADSI provider, interfaces, and constants, see "Related Reading.") A word of caution: Using a clear-text password in a script isn't a sound security practice; this article does so for demonstration purposes only. Either store the script at an extremely safe location or modify the script to prompt the administrator for his or her username and password.
The W3SVC node (IIsWebService class). IIS can host multiple services, the most popular of which are W3SVC, FTP, SMTP, and NNTP. Each of these services has its own node under the machine node. When you use the IIS://localhost/W3SVC pathname argument, you get a W3Svc object derived from the IISWebService class.
The Web site node (IIsWebServer class). A class name such as IIsWebSite (rather than IIsWebServer) would more clearly communicate the Web site node's function. Each Web site on your server is represented by a separate node. To avoid ambiguous references, IIS assigns each Web site a numerical site ID; the default Web site's ID is always 1. To reference the default Web site node in a script, therefore, use that number in the GetObject function's pathname argument. If you have more than one Web site, you can use Metabase Explorer to find each site's ID. In IIS 6.0, the IIS Manager snap-in also displays the site ID, or you can run the following command to display all sites:
To find a site ID for an IIS 5.1 site, run the findweb.vbs script, which resides by default in the %windir%\Inetpub\Adminscripts folder; for IIS 5.0 and IIS 4.0 sites, the file is named findsite.vbs.
The IIS documentation details hundreds of properties on the Web site level. Most of these properties are reflected in the IIS UI, but some, such as the Realm property, have GUI support in IIS 6.0 only. The IIsWebServer class also has a few useful methods, including those that start, stop, or pause a Web site. Such methods can be handy for remotely recycling a Web site. Listing 4 shows a sample script to stop and start the default Web site. To start the site only, use the script that Listing 5 shows.
The virtual directory node (IIsWebVirtualDir class). The ROOT virtual directory node, of the IIsWebVirtualDir class, under each Web site node represents that Web site's root location. (Although a Web site's root doesn't appear as a virtual directory in the IIS Manager console, it appears as a virtual directory in the metabase.) You can set hundreds of properties on this node, including the physical path that we've been using as an example. The IIsWebVirtualDir class also supports interesting methods, including several AppCreate functions that let you create Web applications. You can also use the AppCreate function to configure an IIS application's isolation level, and recent AppCreate extensions (e.g., AppCreate3 in IIS 6.0, AppCreate 2 in IIS 5.1 and IIS 5.0) take IIS's advanced isolation capabilities into account.
After you understand the metabase's hierarchy, you're ready to learn how to set, create, and search for IIS configuration data. With this skill, you can accomplish otherwise laborious and error-prone tasks—such as resetting your Web site's home path from one drive to another or creating an identical virtual directory in 1000 Web sites—in minutes flat.
Listing 6 shows a sample script that sets the default Web site's authentication scheme. This script uses the GetObject function to instantiate an object that, based on its path, is mapped to the default virtual directory on our default Web site. The script uses the GetObject function to create an instance of an IIsWebVirtualDir object named oDefaultVdir. Next, the script sets the AuthFlags property to 0 to disable all authentication schemes. The script then sets Windows authentication (AuthNTLM) as the only allowed authentication scheme for the ROOT virtual directory. The script's final line calls the SetInfo function to commit the new values. You can use this type of script to set properties on a node, thereby modifying your IIS server's configuration.
Creating and Deleting Nodes
The most obvious examples of new configuration data that you might need to create are new Web sites or virtual directories. The script that Listing 7, page 60, shows creates a virtual directory in the default Web site when you invoke the script with the virtual directory name and a path to the virtual directory's contents. The script takes two arguments from the command line: the name of the new virtual directory and the physical path. (If these two parameters aren't passed to the script, it terminates.) The script calls the GetObject function to retrieve an object from an existing metabase path, then calls the IADsContainer interface's Create method to create a new node. (For more information about the ADSI IADsContainer interface, see "Related Reading.") This method also takes two arguments: the new node's class and name. The script then sets the physical path and calls SetInfo() to commit the changes. All other properties are inherited from the parent nodes.
Deleting a node is similar to creating it. This task uses the IADsContainer interface's Delete method to perform the delete operation, as Listing 8 shows. In this example, the script takes only one argument: the name of the virtual directory to delete. The script uses the GetObject function to locate the parent node, then uses the IADsContainer Delete method to delete the virtual directory.
Querying for Data
Suppose you want to know where a particular property resides and whether the property is set. For example, suppose you want to determine the level of security compliance on your IIS machine by making sure that your sites and virtual directories allow only a particular type of authentication. To accomplish such tasks, you can use the GetDataPaths function. GetDataPaths returns paths (e.g., IIS://localhost/w3svc/1/root) to all locations in which a specified property exists.
Listing 9 shows a sample script that uses the GetDataPaths method to look up all sites and virtual directories that allow anonymous access. As usual, the script begins by retrieving an object, in this case, the query starting point. (The query will search all subnodes of the specified object.) The script then calls the GetDataPaths method, which takes a string that specifies the property we're looking for. The second argument specifies whether we're looking for any property or only inheritable properties. The GetDataPaths method returns an array of paths, as Figure 3 shows. These results reveal that anonymous authentication is set on the IIS://localhost/W3SVC and IIS://localhost/W3SVC/1/ROOT nodes. To turn off anonymous access, you can use these paths as arguments for additional GetObject calls, as the extended script in Listing 10 shows.
Automating IIS administration can be a big timesaver and a rewarding experience, especially if you administer multiple IIS sites. When you understand the IIS metabase's logical structure and know how to get, set, create, delete, and query IIS configuration data, you can start using your own IIS scripts. Of course, you'll want to add to your scripts some error-handling and parameter-validation functions, which we omitted for the sake of simplicity, but other than that, you're ready to script IIS.
IIS ADSI Provider Reference
Core ADSI interfaces
Constants used in IIS ADSI provider
ADSI container object functions
ADSI Administration with ADSUTIL
IIS 6.0 Direct Metabase Edit feature
Through a Collection
How to convert a VBArray to a JScript Array
METABASE EDITING TOOLS
IIS 6.0 Resource Kit (includes Metabase Explorer)
MetaEdit for IIS 4.0
Corrections to this Article:
- In Brett Hill and Thomas Deml's "Scripting IIS Administration" (December 2003, http://www.win netmag.com, InstantDoc ID 40713), a figure was identified incorrectly. In the print article, Figure 4 should be listed as Figure 3. We apologize for any inconvenience these errors might have caused.