ASPNET_regiis.exe Tool, Setting the Default Version Without Forcing an Upgrade on All Sites

Starting in the first version of ASP.NET, Microsoft has provided a tool to control which version of the framework is registered in IIS. This tool, aspnet_regiis.exe, is quite flexible and with the right understanding of how IIS and ASP.NET work, can be used for most any situation.
The most common parameter is -i. This is the full blown registration of the framework in IIS, including all sites and all vdirs. For example, let's say you wanted your entire server to be registered using ASP.NET v2.0, then you would navigate to the v2.0 framework folder (%windir%\Microsoft.NET\Framework\v2.0.50727) and type aspnet_regiis -i. Likewise, you can navigate to (%windir%\Microsoft.NET\Framework\v1.1.4322) and run the same command to set v1.1 on all sites. This is a great way to repair a broken installation or force a particular framework version to apply to your whole server.
But this catch-all registration is too aggressive for many production servers. That's where the other parameters come in.
To see a detailed list of commands, type aspnet_regiis /? from the command prompt. I'm going to explain two of them: -lk and -sn. With these commands, we can apply the script mappings on just some of the sites on the server and update the default.
Careful on Production Servers
Note: First a disclaimer. Running any aspnet_regiis commands that make a change to IIS will cause all sites on the server to have a short interruption of service. Even if you run the path specific commands which I’ll explain below, all sites will have some downtime. To make changes on production servers without any downtime, you'll need to write a solution to update the script mapping directly. Here's an old article of mine that explains this in more depth:
http://www.orcsweb.com/articles/change_framework.aspx (Someday I'll rewrite that article with an updated script to handle more than 2 versions of the framework, and IIS6 application pool support.)
While I'm offering disclaimers, make sure not to run multiple versions of the framework in the same Application Pool in IIS6.0:
http://weblogs.asp.net/owscott/archive/2006/01/26/436607.aspx

IIS Inheritance
Let me digress again and explain how IIS inheritance works for the script mappings. IIS has a path structure similar to the file system on your computer. For example, the web part of the structure starts with /W3SVC/. Site #1 stores the script mappings in /W3SVC/1/ROOT/. Site #51 stores them in /W3SVC/51/ROOT/, and so on. If the script mappings are specifically set on a particular path then IIS will use those settings. But if they aren't set then it will use the settings from the site or server root.
ASP.NET Version Defaults
When ASP.NET v1.1 was released, if you ran the install, it would apply your settings to all sites on the server, thus changing your framework version from v1.0 to v1.1. This meant that you had to be careful if you wanted to keep version 1.0 as the default. The install had some command line options to give more flexibility.
Version 2.0 of the framework is different and not as aggressive during the installation. Now it doesn't make itself the default and you are required to specifically set it as the default if that is what you want. This is a good thing and is a better behavior than the v1.1 installation.
Don't forget to take a backup
Warning: At this point, make sure to get a backup of IIS before continuing. If you do something wrong, you can restore it and everything will be brought back to its original state.
Displaying The Current Settings
Displaying The Current Settings
The aspnet_regiis tool has a neat way to see what is currently applied in IIS right now. You can do this by typing aspnet_regiis -lk from any framework folder. This will give something like this: (you can do this read-only command without any downtime on your server)
W3SVC/ 1.1.4322.2300
W3SVC/1/ROOT/ 2.0.50727.0
W3SVC/3/root/ 1.1.4322.2300
W3SVC/6/root/ 1.1.4322.2300
W3SVC/7/root/ 2.0.50727.0
Notice on this test server that the root, site #3 and site #6 are using v1.1 of the framework and site #1 and #7 are using v2.0. (Here is an article to find out which site is using which SiteID: http://weblogs.asp.net/owscott/archive/2005/07/29/421058.aspx)
Notice the gaps in numbers as #2, #4 and #5 aren't set. This means that they will inherit their settings from /W3SVC/ which is currently using v1.1.
Now, the issue we have is that when setting up new sites, they will always use version 1.1 of the framework. Since v2.0 has all of the latest and greatest features, we want new sites to use v2.0 but make sure that existing sites aren't changed. In our example here, let's say that we want to upgrade the server to use v2.0 of the framework as the default version, but we don't want sites #2, #3 or #6 to be upgraded.
If we run aspnet_regiis -i then we'll force everything to version 2.0 which we don't want. And if we upgrade just the root, then too many of the sites will be upgraded, which is also what we don't want.
The Magic
The trick is to force all sites that you don't want to upgrade to use v1.1, and then we can upgrade the root to v2.0. Then all new sites created after this will use v2.0.
Sites #3 and #6 are easy, they are already done for us. But site #2 needs to be set to specifically use v1.1 of the framework. This can be done by running aspnet_regiis from the v2.0 framework folder using this command: aspnet_regiis -sn W3SVC/2/ROOT/. Now running aspnet_regiis -lk will return this:
W3SVC/ 1.1.4322.2300
W3SVC/1/ROOT/ 2.0.50727.0
W3SVC/2/Root/ 1.1.4322.2300
W3SVC/3/root/ 1.1.4322.2300
W3SVC/6/root/ 1.1.4322.2300
W3SVC/7/root/ 2.0.50727.0
For the purpose of this example, we're going to let site #4 and #5 continue to inherit from the root, so after the next step they will be upgraded (using inheritance) to use version 2.0 of the framework.
The final step is to update the W3SVC/ node without touching anything else. As I'm sure you've guessed by now, this is done using: aspnet_regiis -sn W3SVC/.  Now we're done, let's look at the final result:
W3SVC/ 2.0.50727.0
W3SVC/1/ROOT/ 2.0.50727.0
W3SVC/2/Root/ 1.1.4322.2300
W3SVC/3/root/ 1.1.4322.2300
W3SVC/6/root/ 1.1.4322.2300
W3SVC/7/root/ 2.0.50727.0
Success! Now sites #4 and #5 and all new sites will use the W3SVC/ setting, which is v2.0. Sites #1 and #7 will also use v2.0 because they were specifically set. Sites #2, #3 and #6 will continue running version 1.1 of the framework.
Summary
We've applied version 2.0 of the framework as the system default while allowing some sites to continue to run version 1.1 of the framework.