Introducing IIS 7.0 Configuration Architecture

You can use IIS 7.0 to publish information on intranets, extranets, and the Internet. Because today’s Web sites use related features, such as ISAPI filters, ASP, ASP.NET, CGI, and the .NET Framework, IIS bundles these features as part of a comprehensive offering. What you need to know right now about IIS 7.0 is how IIS 7.0 uses the configuration schema and its global configuration system. In Chapter 2, you’ll learn about the available setup features and the related configuration modules.

IIS 7.0 Configuration Schema

Unlike IIS 6, in which the main configuration information is stored in metabase files, IIS 7.0 has a unified configuration system for storing server, site, and application settings. You can manage these settings by using an included set of managed code, scripting APIs, and management tools. You can also manage these settings by directly editing the configuration files themselves. Direct editing of configuration files is possible because the files use XML and are written in plain-language text files based on a predefined set of XML schema files.

Note IIS 7.0 always takes the master state for configuration from the configuration files. This is a dramatic change from IIS 6, in which the master state was taken from the in-memory configuration database, which was flushed periodically to disk.

Using the XML schema to specify the configuration settings ensures that the related configuration files are well-structured XML, which is easy to modify and maintain. Because configuration values are stored using easy-to-understand text strings and values, they are easy to work with. By examining the schema itself, you can determine the exact set of acceptable values for any configuration option. IIS shares the same schema with ASP.NET configuration, ensuring that configuration settings for ASP.NET applications are just as easy to manage and maintain.

On an IIS server, schema files are stored in the %SystemRoot%\System32\Inetsrv \Config\Schema directory. The four standard schema files are:

  • IIS_schema.xml This file provides the IIS configuration schema.
  • ASPNET_schema.xml This file provides the ASP.NET configuration schema.
  • FX_schema.xml This file provides the .NET Framework configuration schema (providing features beyond what the ASP.NET schema offers).
  • rscaext.xml This file provides the Runtime Status and Control API (RSCA) configuration schema, providing dynamic properties for obtaining detailed runtime data.

IIS reads in the schema files automatically during startup of the application pools. The IIS schema file is the master schema file. Within the IIS schema file, you’ll find configuration sections for each major feature of IIS, from application pooling to failed request tracing. The ASP.NET schema file builds on and extends the master schema with specific configuration sections for ASP.NET. Within the ASP.NET schema file, you’ll find configuration sections for everything from anonymous identification to output cache settings. The FX schema file builds on and extends the ASP.NET schema file. Within the FX schema file, you’ll find configuration settings for application settings, connection strings, date-time serialization, and more.

Whereas configuration sections are also grouped together for easier management, section groups do not have schema definitions. If you want to extend the configuration features and options available in IIS, you can do this by extending the XML schema. You extend the schema by following these basic steps:

  1. Specify the desired configuration properties and the necessary section container in an XML schema file.
  2. Place the schema file in the %SystemRoot%\System32\Inetsrv\Config\Schema directory.
  3. Reference the new section in IIS 7.0’s global configuration file.

The basic syntax for a schema file is as follows:


The text within this section is a comment. It is standard practice to provide introductory details in the comments at the beginning of the schema file.
     <sectionSchema name="configSection1">
     <sectionSchema name="configSection2">
     <sectionSchema name="configSection3">

As an administrator or developer, you don’t necessarily need to be able to read and interpret XML schemas to succeed. However, because having a basic understanding of schemas is helpful, I’ll introduce the essentials. Within schema files, configuration settings are organized into sets of related features called schema sections. The schema for a configuration section is defined in a <sectionSchema> XML element. For example, the features related to the HTTP listener in IIS are defined with a schema section named system.applicationHost/listenerAdapters. In the IIS_schema.xml file, this section is defined as follows:


<sectionSchema name="system.applicationHost/listenerAdapters">
 <collection addElement="add" >
  <attribute name="name" type="string" required="true" isUniqueKey="true" />
  <attribute name="identity" type="string" />
  <attribute name="protocolManagerDll" type="string" />
  <attribute name="protocolManagerDllInitFunction" type="string" />

This schema definition states that the system.applicationHost/listenerAdapters element can contain a collection of add elements with the following attributes:

  • name A unique string that is a required part of the add element.
  • identity An identity string that is an optional part of the add element.
  • protocolManagerDll A string that identifies the protocol manager DLL.
  • protocolManagerDllInitFunction A string that identifies the initialization function for the protocol manager DLL.

An attribute of an element is either optional or required. If the attribute definition states required="true" as with the name attribute, the attribute is required and must be provided when you are using the related element. Otherwise, the attribute is considered optional and does not need to be provided when you are using the related element. In addition to being required, attributes can have other enforced conditions, including:

  • isUniqueKey If set to true, the related value must be unique.
  • encrypted If set to true, the related value is expected to be encrypted.

With some attributes, you’ll see default values and possibly an enumerated list of the acceptable string values and their related internal values. In the following example, the identityType attribute has a default value of NetworkService and a list of other possible values:


<attribute name="identityType" type="enum" defaultValue="NetworkService">
 <enum name="LocalSystem" value="0"/>
 <enum name="LocalService" value="1"/>
 <enum name="NetworkService" value="2"/>
 <enum name="SpecificUser" value="3"/>

The friendly name of a value is provided to make the value easier to work with. The actual value used by IIS is provided in the related value definition. For example, if you set identityType to LocalService, the actual configuration value used internally by IIS is 2.

As a standard rule, you cannot use enumerated values in combination with each other. Because of this, the identityType attribute can have only one possible value. In contrast, attributes can have flags, which can be used together to form combinations of values. In the following example, the logEventOnRecycle attribute uses flags and has a default set of flags that are used in combination with each other:


<attribute name="logEventOnRecycle" type="flags" defaultValue="Time,
Memory, PrivateMemory">
 <flag name="Time" value="1"/>
 <flag name="Requests" value="2"/>
 <flag name="Schedule" value="4"/>
 <flag name="Memory" value="8"/>
 <flag name="IsapiUnhealthy" value="16"/>
 <flag name="OnDemand" value="32"/>
 <flag name="ConfigChange" value="64"/>
 <flag name="PrivateMemory" value="128"/>

Again, the friendly name is provided to make the value easier to work with. The actual value used by IIS is the sum of the combined flag values. With a setting of “Time, Requests, Schedule,” the logEventOnRecycle attribute is set to 7 (1+2+4=7).

Attribute values can also have validation. IIS performs validation of attribute values when parsing the XML and when calling the related API. Table 1-1 provides an overview of the validators you’ll see in schemas.


IIS 7.0 Global Configuration System

IIS uses a global configuration system that is difficult to understand at first but gets easier and easier to understand once you’ve worked with it awhile. Because there’s no sense trying to ease into this, I’ll dive right in. If you’ll hang with me for a few pages, I’ll get you through the roughest parts and zero in on exactly what you need to know—I promise.

IIS configuration settings are stored in configuration files that together set the running configuration of IIS and related components. One way to think of a configuration file is as a container for the settings you apply and their related values. You can apply multiple configuration files to a single server and the applications it is running. Generally, you manage configuration files at the .NET Framework root level, the server root level, and the various levels of a server’s Web content directories. A server’s Web content directories include the root directory of the server itself, the root directories of configured Web sites, and any subdirectories within Web sites. The root levels and the various levels of a server’s Web content directories can be described as containers for the settings you apply and their values. If you know a bit about object-oriented programming, you might expect the concepts of parent-child relationship and inheritance to apply—and you’d be right.

Through inheritance, a setting applied at a parent level becomes the default for other levels of the configuration hierarchy. Essentially, this means that a setting applied at a parent level is passed down to a child level by default. For example, if you apply a setting at the server root level, the setting is inherited by all Web sites on the server and by all the content directories within those sites.

The order of inheritance is as follows:


NET Framework root ➔ server root ➔ Web Site root ➔ top-level directory ➔ subdirectory

This means that the settings for the current .NET Framework root are passed down to IIS, the settings for IIS are passed down to Web sites, and the settings for Web sites are passed down to content directories and subdirectories. As you might expect, you can override inheritance. To do this, you specifically assign a setting for a child level that contradicts a setting for a parent. As long as overriding a setting is allowed (that is, overriding isn’t blocked), the child level’s setting will be applied appropriately. To learn more about overriding and blocking, see Chapter 5.

When working with the configuration files, keep the following in mind:

  • The .NET Framework root IIS applies depends on the current running version of ASP.NET and the .NET Framework. The default configuration files for the .NET Framework root are Machine.config and Web.config, which are stored in the %SystemRoot%\\Framework\Version\Config\Machine.config directory. Machine.config sets the global defaults for the .NET Framework settings in addition to some ASP.NET settings. Web.config sets the rest of the global defaults for ASP.NET. See Chapter 8, “Running IIS Applications,” and Chapter 9, “Managing Applications, Application Pools, and Worker Processes,” for more information about configuring the .NET Framework and ASP.NET.
  • The default configuration file for the server root is ApplicationHost.config, which is stored in the %SystemRoot%\System32\Inetsrv\Config directory. This file controls the global configuration of IIS. See Chapter 5 for more information about configuring IIS servers.
  • The default configuration file for a Web site root is Web.config. This file is stored in the root directory of the Web site to which it applies and controls the behavior for the Web site. See Chapters 8 and 9 for more information about configuring IIS applications.
  • The default configuration file for a top-level content directory or a content subdirectory is Web.config. This file is stored in the content directory to which it applies and controls the behavior of that level of the content hierarchy and downwards. See Chapter 6 for more information about configuring content directories.

In some cases, you may want a .config file to include some other .config file. This can be done by using the configSource attribute to refer to the .config file containing the settings you want to use. Currently, the referenced .config file must reside in the same directory as the original .config file. Note that this behavior may change to allow .config files in other directories to be used. To see how this works, consider the following example from the ApplicationHost.config file:


<?xml version="1.0" encoding="UTF-8"?>
<!-- applicationHost.config -->
   <error statusCode="401" prefixLanguageFilePath="%SystemDrive%\
inetpub\custerr" path="401.htm" />
   <error statusCode="403" prefixLanguageFilePath="%SystemDrive%\
inetpub\custerr" path="403.htm" />
   <error statusCode="404" prefixLanguageFilePath="%SystemDrive%\
inetpub\custerr" path="404.htm" />
   <error statusCode="405" prefixLanguageFilePath="%SystemDrive%\
inetpub\custerr" path="405.htm" />
   <error statusCode="406" prefixLanguageFilePath="%SystemDrive%\
inetpub\custerr" path="406.htm" />
    <error statusCode="412" prefixLanguageFilePath="%SystemDrive%\
inetpub\custerr" path="412.htm" />
    <error statusCode="500" prefixLanguageFilePath="%SystemDrive%\
inetpub\custerr" path="500.htm" />
    <error statusCode="501" prefixLanguageFilePath="%SystemDrive%\
inetpub\custerr" path="501.htm" />
    <error statusCode="502" prefixLanguageFilePath="%SystemDrive%\
inetpub\custerr" path="502.htm" />

In this example, error elements specify how certain types of HTTP error status codes should be handled. If you wanted to customize the error handling for a server, you might want to extend or modify the default values in a separate .config file and then reference the .config file in ApplicationHost.config. To do this, you would update the ApplicationHost.config file to point to the additional .config file. An example follows.


<?xml version="1.0" encoding="UTF-8"?>
<!-- applicationHost.config -->
  <httpErrors configSource=errorMode.config />

You would then create the errorMode.config file and store it in the same directory as the ApplicationHost.config file. The following is an example of the contents of the errorMode.config file:


<?xml version="1.0" encoding="UTF-8"?>
<!-- errorMode.config -->
  <error statusCode="401" prefixLanguageFilePath="%SystemDrive%\inetpub\
custerr" path="401.htm" />
  <error statusCode="403" prefixLanguageFilePath="%SystemDrive%\inetpub\
custerr" path="403.htm" />
  <error statusCode="404" prefixLanguageFilePath="%SystemDrive%\inetpub\
custerr" path="404.htm" />
  <error statusCode="405" prefixLanguageFilePath="%SystemDrive%\inetpub\
custerr" path="405.htm" />
  <error statusCode="406" prefixLanguageFilePath="%SystemDrive%\inetpub\
custerr" path="406.htm" />
  <error statusCode="412" prefixLanguageFilePath="%SystemDrive%\inetpub\
custerr" path="412.htm" />
  <error statusCode="500" prefixLanguageFilePath="%SystemDrive%\inetpub\
custerr" path="500.htm" />
  <error statusCode="501" prefixLanguageFilePath="%SystemDrive%\inetpub\
custerr" path="501.htm" />
  <error statusCode="502" prefixLanguageFilePath="%SystemDrive%\inetpub\
custerr" path="502.htm" />

When you make these or other types of changes in configuration files, you don’t need to worry about restarting IIS or related services. IIS automatically picks up the changes and uses them. In these examples, you’ll note that we’re working with the system.webServer section of the configuration file. As per the schema definition files, all settings are defined within specific configuration sections. Although sections cannot be nested, a section can exist within a section group, and that section group can in turn be contained in a parent section group. A section group is simply a container of logically related sections.

In ApplicationHost.config, section groups and individual sections are defined in the configSections element. The configSections element controls the registration of sections. Every section belongs to one section group. By default, ApplicationHost.config contains these section groups:

  • system.applicationHost Defines the following sections: applicationPools, configHistory, customMetadata, listenerAdapters, log, sites, and webLimits.
  • system.webServer Defines the following sections: asp, caching, cgi, defaultDocument, directoryBrowse, globalModules, handlers, httpCompression, httpErrors, httpLogging, httpProtocol, httpRedirect, httpTracing, isapiFilters, modules, odbcLogging, serverRuntime, serverSideInclude, staticContent, urlCompression, and validation. Includes the security and tracing subgroups.
  • A subgroup of system.webServer that defines the following sections: access, applicationDependencies, authorization, ipSecurity, isapiCgiRestriction, and requestFiltering. Includes the authentication subgroup.
  • A subgroup of that defines the following sections: anonymousAuthentication, basic-Authentication, clientCertificateMappingAuthentication, digestAuthentication, iisClientCertificateMappingAuthentication, and windowsAuthentication.
  • A subgroup of that defines the traceFailedRequests and traceProviderDefinitions sections.

In ApplicationHost.config, section groups and individual sections are defined as follows:


 <sectionGroup name="system.applicationHost">
  <section name="applicationPools" allowDefinition="AppHostOnly"
overrideModeDefault="Deny" />
  <section name="configHistory" allowDefinition="AppHostOnly"
overrideModeDefault="Deny" />
  <section name="customMetadata" allowDefinition="AppHostOnly"
overrideModeDefault="Deny" />
  <section name="listenerAdapters" allowDefinition="AppHostOnly"
overrideModeDefault="Deny" />
  <section name="log" allowDefinition="AppHostOnly"
overrideModeDefault="Deny" />
  <section name="sites" allowDefinition="AppHostOnly"
overrideModeDefault="Deny" />
  <section name="webLimits" allowDefinition="AppHostOnly"
overrideModeDefault="Deny" />
 <sectionGroup name="system.webServer">

In Machine.config, you’ll also find definitions for section groups and individual sections. These are similar to those used in ApplicationHost.config but are used for configuring the .NET Framework and some ASP.NET settings. When working with either .config file, keep in mind that a section is the basic unit of deployment, locking, searching, and containment for configuration settings. Every section has a name attribute and optional allow-Definition and overrideModeDefault attributes. The name attribute sets the unique section name. The allowDefinition attribute specifies the level at which the section can be set:

  • Everywhere The section can be set in any configuration file including directories mapped to virtual directories that are not application roots, and their subdirectories. Because this is the default setting, a section that doesn’t have an allowDefinition attribute uses this setting automatically.
  • MachineOnly The section can be set only in ApplicationHost.config or Machine.config.
  • MachineToWebRoot The section can be set only in the .NET Framework root’s Machine.config or Web.config file, or in ApplicationHost.config.
  • MachineToApplication The section can be set only in the .NET Framework root’s Machine.config or Web.config file, in ApplicationHost.config, or in Web.config files for application root directories.
  • AppHostOnly The section can be set only in Web.config files for application root directories.

The OverrideModeDefault attribute sets the default lockdown state of a section. Essentially, this means that it controls whether a section is locked down to the level in which it is defined or can be overridden by lower levels of the configuration hierarchy. If this attribute is not set, the default value is Allow. With Allow, lower level configuration files can override the settings of the related section. With Deny, lower level configuration files cannot override the settings of the related section. As discussed in Chapter 5, you’ll typically use location tags to lock or unlock sections for specific Web sites or applications.

Because the complete configuration settings of a server and its related sites and applications are stored in the configuration files, you easily can back up or duplicate a server’s configuration. Backing up a server’s configuration is a simple matter of creating a copy of the configuration files. Similarly, duplicating a server’s configuration on another server is a simple matter of copying the source configuration files to the correct locations on another server.