Migration to IIS 6 can be daunting. Depending on your hosting configuration, the process can take weeks. With careful planning and research, a successful migration is more easily achieved.
This article will address migration to IIS 6 from IIS 5 and issues you may encounter with applications and hosting configurations. Details about data synchronization, permissions, IIS settings, and other administrative tasks will also be provided. If your Web site is not already load balanced, now is a perfect time to do it because you'll already be moving settings and files anyway, not to mention the availability and scalability benefits. Glean what information you need as it applies to your scenario.
Initial Specs
My company hosts more than100 Web sites across multiple shared servers running Win2k/IIS5. Prior to the IIS 6 transition, none were load balanced. A majority of the Web sites use basic ASP, while others consist of static HTML and newer ASP.Net Web sites. In addition, portions of the Web sites use session/application variables. Of these Web sites, most use a local instance of SMTP server, and a few have FTP access.
The basic requirement of load balancing requires at least two servers. Therefore, two dual-processor Win2k3 servers (Web Edition), each with ample disk space, are used. Our Web site content is currently stored locally. Utilizing a NAS solution would alleviate file replication issues (detailed later in this article). Load balancing is done via a network device (BIG-IP) configured to run in a "Round Robin" fashion with session affinity set to 10 minutes (a.k.a. sticky sessions). By using sticky sessions, session-based applications can continue to work normally, albeit only for the set affinity. If you do not use sticky sessions, session or application data may be lost from request to request.
A normal Win2k3 build was performed on our server build out; however, only the application server role was specified and ASP.Net/FTP services enabled. A separate partition was also used to isolate all Web server related activities, including content, log files, COM components, and SMTP service files. Previous to IIS 6, this was not as easy.
Data Synchronization
From a load balancing perspective, synchronizing data across servers in the Web farm is extremely important so that users see the same data, regardless of which server services the request. There are many products to choose from in this regard. Products like Microsoft DFS, robocopy, and other third-party solutions can make it hard to decide. I needed real-time synchronization capabilities, which robocopy couldn't provide, and DFS seemed excessive. After reviewing many of the third-party solutions, I chose PeerSync from Peersoft. PeerSync installs as a service, syncs files instantly (services can "listen" on OS level files changes), and can exclude certain directories and open files. Although I support this product, it is expensive. The heavy feature set went mostly unused, however the performance and reliability of the service is excellent given the amount of data to be synchronized.
I configured the product in the following way:
- Multiple machine real-time setup (refer to support documentation for additional information)
- Synchronized only the Web site content (e.g.
e:inetpubsites
) - Excluded directory "/catalog.wci" and temporary files created by our deployment software
IIS 6 Metabase
The move to IIS 6 makes replicating configurations across multiple servers much easier. Formerly, the metabase was stored in a binary format not easily editable. Now configs are stored in a XML format that can be copied from server to server (with small changes). This can save vast amounts of time when managing a server in your Web farm. Although products such as MS Application server can be helpful, you can opt for the poor man's solution. This involves using one server (could be any in the farm) to manage IIS settings and then use the command-line tools that come with IIS to create a batch file to sync the metabase across the other servers.
For example, if you have two servers in your web farm (PRODIIS1 & PRODIIS2) and a new request requiring you to create a new Web site. From IIS Manager on PRODIIS1, you create the Web site but how do you get the settings over to PRODIIS2 without recreating the same settings? Create a batch file with the following commands:
cscript c:windowssystem32iiscnfg.vbs /s IIS1 /copy /ts PRODIIS2
cscript replace_text_in_file.vbs //nologo "172.7.1" "172.7.2" "\PRODIIS2c$windowssystem32inetsrvmetabase.xml"
The first line executes the IIS 6 CLT to export the "PRODIIS1" metabase file to "PRODIIS2". It removes any machine specific settings in the process. However, since IP addresses are going to be machine specific you will have to handle this case accordingly. I would recommend using a standard IP naming convention where each server is subnetted in a way that every server replicated Web site ends with the same mask. So if your web farm consisted of five Web sites with two servers, the IP's would be allocated as demonstrated in the table below.
Web Site | PRODIIS1 IP | PRODIIS2 IP |
www.domain1.com | 172.7.1.1 | 172.7.2.1 |
www.domain2.com | 172.7.1.2 | 172.7.2.2 |
www.domain3.com | 172.7.1.3 | 172.7.2.3 |
www.domain4.com | 172.7.1.4 | 172.7.2.4 |
www.domain5.com | 172.7.1.5 | 172.7.2.5 |
This configuration would support up to 255 Web sites, which is adequate for a typical shop. Additionally, it will make your network administrator happy when it comes time to configure the load balancer.
Looking at the batch script again, line two uses the knowledge of your IP naming convention to replace the IP addresses synchorized from "PRODIIS1" to those belonging to "PRODIIS2". The script "replace_text_in_file.vbs" is provided in the article download.
SMTP and FTP
There are a few subtle issues involving SMTP and FTP services, such as the absence of CDONTS. Your e-mail form may choke if you don't take one simple measure: copy cdonts.dll from a Win2k machine (located in system32) and copy to the system32 directory. Or, if you're feeling a bit more daring, you can convert all the CDONTS calls to CDO, which is a good option depending on the amount of calls used. I would caution against the second method if you're in a hosting situation where your clients expect CDONTS functionality.
For SMTP management, consider replacing references to the system partition (usually c:inetpubmailroot) and place on your data drive. Do this by opening up the metabase file and do a search/replace. You will want to copy the directory structure as well.
FTP services aren't much different than in IIS 5 except for the new feature for isolated FTP sites. Be certain you use the option "Do not isolate users". Otherwise you'll generate a "Home directory inaccessible" error message when logging into the site.
IIS 5 to IIS 6 Migration
Physically moving Web sites from server to server can vary greatly between organizations. Consequently, it's difficult to detail every step. Most migrations involve three main areas: IIS settings, data, and intangibles. The first two areas are straightforward while the last deals with any specialized setting/service that may also need to run on the new servers. This could encompass anything from COM components to custom Windows services.
Depending on the number of Web sites and their inherent application setting complexities, you will have to decide on moving IIS settings manually or in an automated fashion. "Manually" is characterized simply by recreating the Web site(s) in IIS manager with the possibility of referencing a metabase dump (check out absutil.vbs). The automated route involves using a tool like the IIS 6 Migration tool (download here). You may even take it a step further and write a batch utility to move all the Web sites at once. An automated, single Web site migration is detailed as follows.
The IIS 6 migration tool (IISMT) allows you to migrate a Web site from an IIS 5 server to IIS 6. This command-line tool runs off the destination IIS 6 machine. If you take a peek at documentation associated with the download, you'll notice a number of options. Most significant are the options for:
- "Web site/W3SVC" - Name of site identifier of old source Web site
- server_binding - String containing new IP address, port, host header (e.g. 172.7.1.1:80: )
- site_id - Usually a random 9 or 10 digit number (can usehttp://www.winguides.com/security/password.php to generate ID). If created in IIS, the site ID is fashioned after the name of the Web site (IIS 6 no longer uses auto identifiers as a security precaution)
- configonly - Moves only IIS settings, not Web site data
Running IISMT while moving data is the default behavior, but it also moves ACL's. Although this may be desirable, local groups are moved, which can result in broken SID's on the destination machine. If this applies to you, opt to move data by a simple xcopy:
xcopy \targete$inetpubsitesdomain.com e:inetpubsitesdomain.com /E /H /Y
Alternatively, the Microsoft SubInAcl command-line tool can work to replace/delete SID's. Or even a more power utility SetACL (available at http://setacl.sourceforge.net). This tool is superior to CACLS/XCACLS and doesn't suffer from the inheritance bug (http://support.microsoft.com/?id=834721)
Putting It All Together
Now that I've described some of the concepts and tools required of a load balanced environment, let's expound on the earlier example of hosting five Web sites. Imagine they currently reside on a single, shared IIS 5 server and must be moved. The following table lists the fake source Web site information:
Domain | W3SVC # | IP Address | Document Root |
www.domain1.com | 1 | 172.6.1.1 | e:inetpubsiteswww.domain1.comwwwroot |
www.domain2.com | 2 | 172.6.1.2 | e:inetpubsiteswww.domain2.comwwwroot |
www.domain3.com | 3 | 172.6.1.3 | e:inetpubsiteswww.domain3.comwwwroot |
www.domain4.com | 4 | 172.6.1.4 | e:inetpubsiteswww.domain4.comwwwroot |
www.domain5.com | 5 | 172.6.1.5 | e:inetpubsiteswww.domain5.comwwwroot |
OLDIIS - Host info
With this information in hand, it's time to start moving IIS settings and data! Start by logging into the primary IIS 6 server (PRODIIS1 in this example). Now follow these steps for each site, substituting the correct source and destination info (www.domain1.com used below)
iismt OLDIIS w3svc/1 /path "e:inetpubsitesdomain1.comwwwroot" /serverbindings 172.6.1.1:80: /siteid 842798180 /overwrite /configonly
* Make sure /siteid value is unique for each Web site. To generate ID use link provided earlier- Copy data off target server like so:
xcopy \OLDIISe$inetpubsitesdomain1.com e:inetpubsitesdomain1.com /E /H /Y
- Run IIS sync batch command from PRODIIS1
- Set any ACL's if need be on all servers in the Web farm. I recommend creating another batch file to ACL common routines such as setting basic authentication. I've provided such a sample in the article download.
Conclusion
Some tips for load balancing and IIS 6:
- Use standard internal IP naming conventions
- Increase upload limit for ASP application by setting the property AspMaxRequestEntityAllowed in the IIS metabase. Default value is a measly 200k
- In IIS manager under the configuration button, enable parent paths so your SSI calls work with relative pathing
- If you use a local IUSR account for anonymous users, rename it so that it isn't machine specific (e.g. IUSR_PRODUCTION instead of IUSR_PRODIIS1). Same goes for the IWAM account
- Ensure that your machine.config files on each server match
- Create a static machineKey element in the machine.config file. Refer to KB article (http://support.microsoft.com/default.aspx?scid=kb;en-us;Q312906) to create validation and decryption keys
- If you encounter an ASP.net error saying something like "Access denied to 'E:inetpubsitesdomain1.comwwwrootadminweb.config'. Failed to start monitoring file changes". Add the "NT AUTHORITYNETWORK SERVICE" account to the directory in question
- Files that are writable by an application should be placed in separate directory so that permissions can be granted on the directory rather than individual files. Otherwise the data synchronization service will wipe out ACL information
- Create separate application pools for Web sites with direct FTP access or those have they extensive programming. Logically name these pools too (e.g. app.domain1.com)
About the Author
Gregg Faus, MCAD.Net, is a Senior Web Software Engineer for Company 39 / Parsons Brinckerhoff. He works with a breadth of technologies including ASP.Net, C#, SQL Server, Flash, and Content Management Systems using Interwoven.