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.

  

Hunting Zombies

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'

Powershell can be a sensitive soul...

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> IIS:

PS> cd '\Sites\Default Web Site'

PS> dir

 directory    test    C:\inetpub\wwwroot\test

PS> New-WebVirtualDirectory test -physicalpath 'c:\inetpub\wwwroot\test'

PS> dir

 virtualDirectory    test        C:\inetpub\wwwroot\test

PS> Remove-WebVirtualDirectory test

PS> dir

 directory           test        C:\inetpub\wwwroot\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> cd \inetpub\wwwroot\

PS> mkdir test

PS> IIS:

PS> cd '\Sites\Default Web Site'

PS> dir

 directory    test    C:\inetpub\wwwroot\test

PS> New-WebVirtualDirectory Test -physicalpath 'c:\inetpub\wwwroot\test

PS> dir

directory           test        C:\inetpub\wwwroot\test

virtualDirectory    Test        C:\inetpub\wwwroot\test

> Remove-WebVirtualDirectory Test

> dir

directory           test        C:\inetpub\wwwroot\test

virtualDirectory    Test        C:\inetpub\wwwroot\test

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.



See Also