I won’t re-pave this oft-visited topic, but want to mention a few interesting twists I encountered and solved moving a number of IIS sites from Windows 2000 Server to Windows 2003 Server. Microsoft provides a migration tool for converting older IIS metabases to work with IIS 6, but it is not a complete solution.
The first thing I did after migration was “complete” was to go into IIS Manager, right-click on the server node, select Properties and check the “Enable Direct Metabase Edit” box. This enabled me to open the metabase directly with Notepad (c:\windows\system32\inetsrv\metabase.xml).
The old system had logical drives C:, D: and E: whereas the new system just has a single C: drive. On the old system, web sites were located on D:\websites. A global search and replace changed them all to C:\websites. A lot quicker and less error-prone than doing that through the UI for a dozen sites.
This particular server had a few web sites that redirect to a specific URL or file rather than to a vdir, and it turns out that these are saved in the metabase with a reference to the Windows directory as their “home directory”. Moral of the story: when migrating, if your Windows directory has a different name on the new server (in my case, the old one was C:\Winnt) then do a global search and replace on that string as well.
Editing the metabase sounds scary; you certainly want to make a backup copy before messing with it. But it’s just XML, and if you’re careful with your search and replace expressions it should be no big deal.
Once you save the updated metabase file, go back to IIS Manager, right-click on the server node, and select All Tasks | Restart IIS. Frankly I don’t know if IIS detects the metabase changes and reads them in on the fly and if it does so, whether this works reliably; I figure that it’s best to force a complete restart to be sure. Besides if you’re just setting up a new server, it’s not like it’s going to disturb live users.
If you’re using ASP.NET you will probably want to run aspnet_regiis -i against the desired version of the .NET framework. This is how I noticed some of the above issues; the utility creates a log file (and notifies you it’s done so, and where it’s located) if it encounters any errors. Search that log file for the word fragment “fail” and any failure to create or find a directory is probably related to incorrect paths within the IIS metabase.
{ 2 comments… read them below or add one }
I can’t tell you how many times aspnet_regiis -i has saved my butt! I remember that it was particularly useful when .NET 1.1 was installed on a server for the first time – although I don’t know if the issue still exists for .NET 2.0
Bob responds: Ah, so you’ve encountered the old “installed IIS after .NET” problem, too ;-) Yes, the issue exists and is compounded for later .NET versions because you may have the need to move some or all sites to (say) 2.0 from 1.1. In that case you’d run the 2.0 version of aspnet_regiis — using the -i argument if you want to do this for all sites, or the -sn argument if you want to do it for selected sites. You can list what sites are using what runtimes with aspnet_regiis -lk. Scott Forsyth has an excellent summary post here with more info.
That would explain how hosting companies manage the .NET runtime for each site in each app pool, would it not?
Bob responds: Sort of. You can set the runtime to use on a site by site basis interactively in IIS, too; aspnet_regiis is a way to do this in a batch mode for multiple sites. I frankly don’t know if IIS Manager calls aspnet_regiis to do this work for a single site, or if some other mechanism is used. But it makes sense that IIS would do so, because otherwise the IIS snap-in would have to be updated for each new framework release.
Another issue is that you can’t run different versions of the framework within the same app pool; that has to be managed from IIS as far as I know. If anyone has more experience with this, please chime in. Oh — and you have to make sure each version of the .NET framework you want to use has been permitted within the IIS “web services extensions” node. IIS 6 has all of them locked down by default.