Mike Volodarsky's blog

Formerly the core server PM for IIS 7.0 and ASP.NET, now I run LeanSentry.
UPDATES: New troubleshooting guide released! Fix IIS website hangs →

Remove zombie websites from your IIS server

Zombie websites get created whenever the root application of a website is removed, orphaning the rest of the application content in your website.

Because IIS requires the root of the website to be an application, this effectively renders the website inaccessible:

  • It cannot serve requests
  • It does not show up in InetMgr
  • It will likely break many administrative or configuration actions
Just for reference, here is what this looks like in your applicationHost.config:


     <application path="/child1"> <!-- Where is the root app?


(Note: if you remove a parent application that is NOT the root of the site, things will still work fine - even though the child apps may be considered orphaned, they are actually not.  The only change that happens is that content at the parent application's level becomes part of the root application)

Surprisingly, this is actually easy to end up with - just delete the root application of a website instead of deleting the website itself - e.g. by running appcmd delete app "Default Web Site/". Then try to browse to localhost :) .

There is a good article describing how to find these here: Hunting zombies: how to remove orphaned IIS web applications. However, the article does not actually tell you how to remove them, and since you cannot easily remove them from InetMgr, many users seem to be out of luck.

After trying to help a user on the IIS forums here to remove a zombie app, I decided to write a quick tool to do it.

So, here you go:

Download the tool: http://mvolo.com/wp-content/uploads/2012/11/RemoveOrphanedSites.zip.

To run it:

> RemoveOrphanedSites.exe /site:all      <-- Shows all orphaned sites ONLY, does not remove

> RemoveOrphanedSites.exe /site:all /remove     <-- Removes all orphaned sites

> RemoveOrphanedSites.exe "/site:Default Web Site"     <-- Checks if the specific site is orphaned

> RemoveOrphanedSites.exe   <-- Displays help, how to connect to remote servers, etc

Hope this helps everyone who has this problem.



Connecting to IIS 7.0 configuration remotely with Microsoft.Web.Administration

As you know, IIS 7.0 provides a number of ways to manage configuration other then MWA, including IIS Configuration COM objects for script, IIS Configuration COM objects from .NET or native clients, WMI, the IIS Manager tool (inetmgr.exe), and AppCmd. While all of these can be used to manage an IIS 7.0 box remotely (AppCmd with extra help of a remote shell environment or WMI), MWA remains one of the most common options because its so easily accessible from .NET.

Microsoft.Web.Administration uses the IIS 7.0 configuration objects under the covers, just like all of the other management options (except for IIS Manager, which uses the IIS Management service, and WMI, which uses the WMI DCOM remoting infrastructure).

Incidentally, this also means that Microsoft.Web.Administration can be used to remotely manage a Server Core installation.

This is despite the fact that currently Server Core does not support the .NET Framework - and is possible because MWA uses the IIS configuration COM objects as the underlying provider, which is native. So, while you cannot use MWA to manage a Server Core server locally, you can do it by running the .NET program remotely on a normal Windows Server 2008 or Windows Vista SP1 machine. However, you cannot use IIS Manager to manage a Server Core server remotely, because IIS Manager uses the IIS Management Service for remote management over HTTPS, which currently is not available on Server Core.

This brings us to the core of the issue: MWA uses the IIS configuration COM objects to manage the server, and therefore in the remote case requires DCOM access to the remote machine.

By default, DCOM access is blocked by Windows Firewall. Therefore, when you try to connect to a Windows Server 2008 or Windows Vista SP1 computer using Microsoft.Web.Administration, or another mechanism that also uses the IIS Configuration COM objects (everything except for WMI and IIS Manager), you will receive the RPC_S_SERVER_UNAVAILABLE error.

To enable DCOM access, you'll normally need to open TCP/135 for the DCOM port mapper, and the entire dynamic port range between 1024 and 65535 used by DCOM. Obviously, this is not something you want to do, especially not on a production server.

Luckily, DCOM provides a way to specify a fixed port for each COM+ package, which allows to enable remote configuration access by opening two ports:

  1. TCP 135 - DCOM port mapper
  2. A single TCP port for the IIS configuration COM objects

You can read more about this approach in Using Distributed COM with Firewalls.


Go here to skip the reading, and grab the batch file to configure remote IIS config, and the RemoteConfigTest.exe tool to test IIS config connectivity.


Here are the 3 steps to do it:


1) Configure the IIS configuration objects to use a fixed DCOM port

- Run dcomcnfg.exe
- Expand Component ServicesComputersMy ComputerDCOM Config, select the “ahadmin” COM+ package
- Select PropertiesEndpoints tab, click Add:
- Select “Connection-oriented TCP”
- Set fixed port


DCOM configuration

Setting the endpoint configuration:

Setting a fixed DCOM endpoint

For command line usage, or if you are on server core, here is the equivalent:

> REG ADD HKEY_LOCAL_MACHINESOFTWAREClassesAppID{9fa5c497-f46d-447f-8011-05d03d7d7ddc} /v EndPoints /d "ncacn_ip_tcp,0,<PORT>" /t REG_MULTI_SZ /f

(where <PORT> is the TCP port between 1024 and 65535 you'd like to dedicate to IIS config)


2) Open the required ports in the firewall

- Open TCP port 135 for the DCOM port mapper
- Open the selected TCP port

I additionally secure the opened ports as follows:

  1. Private profile only
  2. Set scope to “Local subnet” only, or specific computer addresses on the network
  3. Restrict ports to the process/services that provide DCOM access to the IIS config COM objects 

For command line usage, or if you are on server core, here are the commands:

> netsh advfirewall firewall add rule name="RPC Mapper" dir=in action=allow profile=private remoteip=localsubnet protocol=tcp localport=135 service=RpcSs

> netsh advfirewall firewall add rule name="AHADMIN Fixed Endpoint" dir=in action=allow profile=private remoteip=localsubnet protocol=tcp localport=<PORT> program=%windir%system32dllhost.exe

(where <PORT> is the fixed TCP port you chose in step 1)

You can also use ipsec to restrict access further.


3) Insure adequate access

You will need Administrative privileges on the remote machine in order to use IIS Configuration objects. This means that you either need to be logged in as/impersonating the local Administrator account with a syncronized password, or a domain account that has Administrative privileges on the remote server.

Due to UAC, you will not be able to use a local user other then BUILTINAdministrator, even if that user is a member of the Administrators group on the remote machine (that is, unless you disable UAC).

There are additional things you can do by modifying activation ACLs on the COM+ package or DCOM security settings, but these are out of scope of this post.

4) Reboot 

I've seen cases where a reboot is required to pick up the DCOM changes.  Possibly because RpcSs caches the DCOM activation settings and therefore requires a reboot (its not possible to  restart RpcSs).

If you are unable to connect remotely after going through the steps above, be sure to reboot and try again.

Tools you can use: 

1) Batch file that will perform steps #1 and #2 for you:

> iisremoteconfig.bat 5000 - to setup IIS config access on port 5000

> iisremoteconfig.bat 0 - to remove the IIS config access

(NOTE: A reboot may be required to activate these settings)

2) The RemoteConfigTest.exe tool that will attempt a connection and diagnose the connectivity issues if any:

> RemoteConfigTest.exe

This tool will alert you if you have a firewall connectivity problem, forgot to register the IIS configuration COM objects, or do not have sufficient permissions to use them.