Managing IIS from the Command Line

In this section, we'll take a look at administering IIS 7 outside of IIS Manager. We'll start by examining some common administrative scenarios through the user of AppCmd.exe, and then look at the text-file configuration options that this new version of IIS presents to us.

IIS 7 includes AppCmd.exe, which is a new, one-stop executable for administering essentially every function IIS provides. Through AppCmd, you can create and configure sites, application pools, and virtual directories; start, stop, and recycle sites and pools; examine current activities in the core of the web server service; and generally find, copy, and import configurations of both IIS itself and the ASP.NET subcomponent.

AppCmd takes a logical syntax: you perform an operation, or command, on a specific piece of IIS, or an object. For example, you can list sites (list being the command and site being the object), add applications, delete worker processes, or set configurations.

Tip

You can get a general sense of the scope of functions AppCmd supports by using the /? switch at a command line.

For example, we can list the sites that are stopped on a server by using the following command:

appcmd list sites /state:Stopped

We can add a completely new web site entirely from the command line. Let's add a site named "Booksite" that listens on port 81 and whose content is stored at c:\inetpub\wwwroot\booksite:

appcmd add site /name:BookSite /id:2 /bindings:"http/*:81:" /physicalPath:"C:\inetpub\
wwwroot\booksite"

I can change the identifier for my new site to number 99 using the following command:

appcmd set site "BookSite" /id:99

I can delete the site that I just added as follows:

appcmd delete site "Booksite"

To create a backup, which will allow you to fix unwanted changes to server configuration and return to a configuration that, at one point, functioned correctly, it's a simple one-line command:

appcmd add backup 20071015

You can then display a list of available backups using the first command below, and then restore one of them using the second command (the restore command stops the server, adds the configuration from the backup, and then restarts the server):

appcmd list backups
appcmd restore backup "20071015"

If you start piping output of one command and feeding to another command, you can achieve some useful outcomes. For example, to recycle all application pools, you can use:

appcmd list apppool /xml | appcmd recycle apppool /in

You can also recycle application pools serving a specific web site; in this example, let's say "Company Web":

appcmd list site "Company Web" /xml | appcmd list app /in /xml | appcmd list
apppool/in /xml | appcmd recycle apppool /in
appcmd list app /site.name:"Company Web" /xml | appcmd list apppool /in /xml | appcmd
recycle apppool /in

We can start all of the sites we stopped in the earlier example in this section with the following command:

appcmd list site /state:stopped /xml | appcmd start site /in

You can do directory or file maintenance on a certain directory safely by determining which sites read from a specific location, like C:\inetpub\wwwroot:

appcmd list vdir /physicalPath:C\inetpub\wwwroot /xml | appcmd list app /xml /in |
appcmd list site /in

You can also see what applications are served by worker process 2450:

appcmd list wp 2450 /xml | appcmd list apppool /xml /in | appcmd list app /in

And perhaps useful for a quick scan of serving problems, you can retrieve a list of all sites generating 404 errors, indicating that a page cannot be found by IIS:

appcmd list trace /statusCode:404 /xml | appcmd list site /in

The old IIS metabase now takes on new life and a new format in applicationHost.config, which now forms the central configuration store for an IIS server. It defines all sites, applications, virtual directories, and application pools on a given machine. And, because of the delegated configuration abilities of IIS 7, you can choose from three ways of architecting configurations through text files in IIS 7:

Let's take a look at a configuration file now. To do so:

The configuration files are simple XML files that are easy to parse visually. Plus, with your text editor, you can use the find function in your software to go straight to a section you want to modify, as well as search and replace to change a configuration globally. Here's a sample from the applicationHost.config file on a plain vanilla Windows Server 2008 machine with the Web Server and Application Server roles installed (Example 8-1).

Example 8-1. A sample XML configuration file

-->
    <configSections>
        <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>

        <sectionGroup name="system.webServer">
            <section name="asp" overrideModeDefault="Deny" />
            <section name="caching" overrideModeDefault="Allow" />
            <section name="cgi" overrideModeDefault="Deny" />
            <section name="defaultDocument" overrideModeDefault="Allow" />
            <section name="directoryBrowse" overrideModeDefault="Allow" />
            <section name="fastCgi" allowDefinition="AppHostOnly"
overrideModeDefault="Deny" />
            <section name="globalModules" allowDefinition="AppHostOnly"
overrideModeDefault="Deny" />
            <section name="handlers" overrideModeDefault="Deny" />
            <section name="httpCompression" allowDefinition="AppHostOnly"
overrideModeDefault="Deny" />
            <section name="httpErrors" overrideModeDefault="Deny" />
            <section name="httpLogging" overrideModeDefault="Deny" />
            <section name="httpProtocol" overrideModeDefault="Allow" />
            <section name="httpRedirect" overrideModeDefault="Allow" />
            <section name="httpTracing" overrideModeDefault="Deny" />
            <section name="isapiFilters" allowDefinition="MachineToApplication"
overrideModeDefault="Deny" />
            <section name="modules" allowDefinition="MachineToApplication"
overrideModeDefault="Deny" />
            <section name="odbcLogging" overrideModeDefault="Deny" />
            <sectionGroup name="security">
                <section name="access" overrideModeDefault="Deny" />
                <section name="applicationDependencies" overrideModeDefault="Deny" />
                <sectionGroup name="authentication">
                    <section name="anonymousAuthentication"
overrideModeDefault="Deny" />
                    <section name="basicAuthentication" overrideModeDefault="Deny" />
                    <section name="clientCertificateMappingAuthentication"
overrideModeDefault="Deny" />
                    <section name="digestAuthentication" overrideModeDefault="Deny" />
                    <section name="iisClientCertificateMappingAuthentication"
overrideModeDefault="Deny" />
                    <section name="windowsAuthentication"
overrideModeDefault="Deny" />
                </sectionGroup>
                <section name="authorization" overrideModeDefault="Allow" />
                <section name="ipSecurity" overrideModeDefault="Deny" />
                <section name="isapiCgiRestriction" allowDefinition="AppHostOnly"
overrideModeDefault="Deny" />
                <section name="requestFiltering" overrideModeDefault="Allow" />
            </sectionGroup>
            <section name="serverRuntime" overrideModeDefault="Deny" />
            <section name="serverSideInclude" overrideModeDefault="Deny" />
            <section name="staticContent" overrideModeDefault="Allow" />
            <sectionGroup name="tracing">
                <section name="traceFailedRequests" overrideModeDefault="Allow" />
                <section name="traceProviderDefinitions" overrideModeDefault="Deny" />
            </sectionGroup>
            <section name="urlCompression" overrideModeDefault="Allow" />
            <section name="validation" overrideModeDefault="Allow" />
        </sectionGroup>
    </configSections>