When you run many of the AppFabric configuration commands via PowerShell or the IIS Manager, the result is a change to a web.config file. IIS configuration is hierarchical with settings being inherited from parent nodes. The implication of this is that when determining the correct settings for a web application, a series of configuration files are parsed. An error in any one of these configuration files can lead to an improperly functioning system. The event logs are a good place to look for these errors as the offending configuration files will often be named in the log entry. The AppFabric Dashboard in IIS manager will also let you know if there are errors.
AppFabric has a one-time inheritance model for its configuration. If you choose to provide a configuration setting at a node then this overrides the configuration set at a parent node. The scope / granularity of this is for all AppFabric configuration.
A common issue on a development workstation is configuration getting left behind when the physical path for a web applicaiton is removed without first removing the applicaiton . For example, you map a folder into IIS as a web application, this folder contains other subfolders which in turn are also mapped as web applications. If you remove the parent web application without first removing the child applications then the child configuration remains. It cannot be seen via IIS Manager as there is no way to reach it, however you can easily see it through PowerShell. One of the many great features in PowerShell is the provider model which allows any hierarchical system to be navigated in a consistent way. The canonical example is the file system, most people are used to: cd, dir, etc to navigate around. Well, these same commands (which are actually aliases in PowerShell to standard verb-noun commands) can be used to navigate other hierarchies, for example IIS.
From a PowerShell console running with elevated status (run as Administrator), you can do the following:
First you need to add the IIS Management module to the session:
PS> import-module WebAdministration
You can the navigate the IIS structure by changing the 'drive' to be IIS:
PS> IIS:
PS> ls
Both the dir and ls commands are mapped to the get-childitem PowerShell command via an alias. This provides a standard Windows console or UNIX console experience. Listing the children at the root level gives access to the application pools, web sites and SSL bindings. Following through the example above, navigate to the default web site and then list all of its children. In this case, both the PowerShell provider and IIS Manager show the same web applications.
So, let's makes some zombies (orphaned IIS web applications) to demonstrate the problem.
Create a new folder C:\ZombieParent and add two sub-folders, ZombieChild1 and ZombieChild2. Map the parent folder to a web application called Zombies and convert the two sub folders also to web applications. Re-running the Get-ChildItem command now shows:
You can see the three web applications at the end of the list, in IIS Manager we have:
Let's now remove the parent Zombies web application, in PowerShell we can still see the ZombieChild? web applications:
In IIS Manager we no longer see the ZombieChild1 or ZombieChild2 web applications.
This can be the source of many weird errors when working with AppFabric as it tries to parse configuration for zombie web applications. If you are getting strange behavior it is well worth launching a PowerShell console and going on a zombie hunt. The web applications left behind can be removed via the console: PS> Remove-WebApplication '.\Zombies\ZombieChild1'
Another item that tripped me up when investigating the above is case sensitivity. IIS allows you to promote a physical path to a virtual directory to a web application. In the following example a directory is created in the physical folder for the default web site. This folder is then configured as a virtual directory, and then returned to a physical directory.
PS> cd \inetpub\wwwroot\
PS> mkdir test
PS> cd '\Sites\Default Web Site'
PS> dir
directory test C:\inetpub\wwwroot\test
PS> New-WebVirtualDirectory test -physicalpath 'c:\inetpub\wwwroot\test'
virtualDirectory test C:\inetpub\wwwroot\test
PS> Remove-WebVirtualDirectory test
However if the case of the directory/virtual directory/web application does not match exactly then you get the following behavior:
PS> Import-Module WebAdministration
PS> New-WebVirtualDirectory Test -physicalpath 'c:\inetpub\wwwroot\test'
virtualDirectory Test C:\inetpub\wwwroot\test
> Remove-WebVirtualDirectory Test
> dir
Here we created a new physical directory under the wwwroot folder and then mapped a virtual directory to this location but used a name of Test rather then test. When we Get-ChildItem, we see two entries: 'test' for the physical path and 'Test' for the virtual directory. Then we remove the virtual directory but it is not deleted and no error is reported.
This caused a heap of confusion for me when automating our deployments so beware of case sensitivity! This has been raised with Microsoft as an issue. I found that the ConvertTo-WebApplication cmdlet worked for my needs without the case issues.
Richard Mueller edited Revision 6. Comment: Replace RGB values with color names in HTML to restore colors
Richard Mueller edited Revision 5. Comment: Removed (en-US) from title, added tags
stefsewell edited Revision 4. Comment: Explicitly provide the remove-webapplication command example
Craig Lussier edited Revision 3. Comment: added en-US to tags and title
Stef Sewell edited Revision 1. Comment: Fix typo.
Mike McKeown edited Original. Comment: edits
Yes, but how do you hunt zombies????
=^)
Very good article, but my organisation uses Windows Server 2003 and I don't have access to PowerShell.
How could I find "Zombies" without PowerShell?