Migrating IIS7 from System Drive to a Non-System Drive
As most of you know, IIS is by default installed on C$ in Windows Server 2008 and there is no way to install it on any other drives. The only solution is to migrate it to a different drive is post installation.
Recently i had a situation where the IIS was installed on C$ of a fully functional web server. During the server security review, we had to migrate it to a non-system drive (D$ in our case). It is a security best practice to have the IIS installed on a non-system drive. As the server was in production and we could not afford much downtime on the server, we had to figure out a way to migrate IIS from C$ to D$ with minimal impact and least downtime.
The APPCMD of the Windows Server 2008 is a fantastic utility which helps this migration without much hassles. Migrating IIS from C$ to D$ will include some data migration, log migration, registry key modifications etc.. Writing a batch file to automate this entire migration was the best possible solution and guess what, we found the same from one of the IIS blogs which works like magic:
REM-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
REM PLEASE BE AWARE: SERVICING (I.E. HOTFIXES AND SERVICE PACKS) WILL STILL REPLACE FILES
REM IN THE ORIGINAL DIRECTORIES. THE LIKELIHOOD THAT FILES IN THE INETPUB DIRECTORIES HAVE
REM TO BE REPLACED BY SERVICING IS LOW BUT FOR THIS REASON DELETING THE ORIGINAL DIRECTORIES
REM IS NOT POSSIBLE.
@echo off
IF "%1" == "" goto err
setlocal
set MOVETO=%1:\
REM simple error handling if drive does not exist or argument is wrong
IF NOT EXIST %MOVETO% goto err
REM Backup IIS config before we start changing config to point to the new path
%windir%\system32\inetsrv\appcmd add backup beforeRootMove
REM Stop all IIS services
iisreset /stop
REM Copy all content
REM /O - copy ACLs
REM /E - copy sub directories including empty ones
REM /I - assume destination is a directory
REM /Q - quiet
REM echo on, because user will be prompted if content already exists.
echo on
xcopy %systemdrive%\inetpub %MOVETO%inetpub /O /E /I /Q
@echo off
REM Move AppPool isolation directory
reg add HKLM\System\CurrentControlSet\Services\WAS\Parameters /v ConfigIsolationPath /t REG_SZ /d %MOVETO%inetpub\temp\appPools /f
REM Move logfile directories
%windir%\system32\inetsrv\appcmd set config -section:system.applicationHost/sites -siteDefaults.traceFailedRequestsLogging.directory:"%MOVETO%inetpub\logs\FailedReqLogFiles"
%windir%\system32\inetsrv\appcmd set config -section:system.applicationHost/sites -siteDefaults.logfile.directory:"%MOVETO%inetpub\logs\logfiles"
%windir%\system32\inetsrv\appcmd set config -section:system.applicationHost/log -centralBinaryLogFile.directory:"%MOVETO%inetpub\logs\logfiles"
%windir%\system32\inetsrv\appcmd set config -section:system.applicationHost/log -centralW3CLogFile.directory:"%MOVETO%inetpub\logs\logfiles"
REM Move config history location, temporary files, the path for the Default Web Site and the custom error locations
%windir%\system32\inetsrv\appcmd set config -section:system.applicationhost/configHistory -path:%MOVETO%inetpub\history
%windir%\system32\inetsrv\appcmd set config -section:system.webServer/asp -cache.disktemplateCacheDirectory:"%MOVETO%inetpub\temp\ASP Compiled Templates"
%windir%\system32\inetsrv\appcmd set config -section:system.webServer/httpCompression -directory:"%MOVETO%inetpub\temp\IIS Temporary Compressed Files"
%windir%\system32\inetsrv\appcmd set vdir "Default Web Site/" -physicalPath:%MOVETO%inetpub\wwwroot
%windir%\system32\inetsrv\appcmd set config -section:httpErrors /[statusCode='401'].prefixLanguageFilePath:%MOVETO%inetpub\custerr
%windir%\system32\inetsrv\appcmd set config -section:httpErrors /[statusCode='403'].prefixLanguageFilePath:%MOVETO%inetpub\custerr
%windir%\system32\inetsrv\appcmd set config -section:httpErrors /[statusCode='404'].prefixLanguageFilePath:%MOVETO%inetpub\custerr
%windir%\system32\inetsrv\appcmd set config -section:httpErrors /[statusCode='405'].prefixLanguageFilePath:%MOVETO%inetpub\custerr
%windir%\system32\inetsrv\appcmd set config -section:httpErrors /[statusCode='406'].prefixLanguageFilePath:%MOVETO%inetpub\custerr
%windir%\system32\inetsrv\appcmd set config -section:httpErrors /[statusCode='412'].prefixLanguageFilePath:%MOVETO%inetpub\custerr
%windir%\system32\inetsrv\appcmd set config -section:httpErrors /[statusCode='500'].prefixLanguageFilePath:%MOVETO%inetpub\custerr
%windir%\system32\inetsrv\appcmd set config -section:httpErrors /[statusCode='501'].prefixLanguageFilePath:%MOVETO%inetpub\custerr
%windir%\system32\inetsrv\appcmd set config -section:httpErrors /[statusCode='502'].prefixLanguageFilePath:%MOVETO%inetpub\custerr
REM Make sure Service Pack and Hotfix Installers know where the IIS root directories are
reg add HKLM\Software\Microsoft\inetstp /v PathWWWRoot /t REG_SZ /d %mOVETO%\inetpub\wwwroot /f
reg add HKLM\Software\Microsoft\inetstp /v PathFTPRoot /t REG_SZ /d %MOVETO%\inetpub\ftproot /f
REM Do the same for x64 directories
if not "%ProgramFiles(x86)%" == "" reg add HKLM\Software\Wow6432Node\Microsoft\inetstp /v PathWWWRoot /t REG_EXPAND_SZ /d %MOVETO%inetpub\wwwroot /f
if not "%ProgramFiles(x86)%" == "" reg add HKLM\Software\Wow6432Node\Microsoft\inetstp /v PathFTPRoot /t REG_EXPAND_SZ /d %MOVETO%inetpub\ftproot /f
REM Restart all IIS services
iisreset /start
echo.
echo.
echo ===============================================================================
echo Moved IIS7 root directory from %systemdrive%\ to %MOVETO%.
echo.
echo Please verify if the move worked. If so you can delete the %systemdrive%\inetpub directory.
echo If something went wrong you can restore the old settings via
echo "APPCMD restore backup beforeRootMove"
echo and
echo "REG delete HKLM\System\CurrentControlSet\Services\WAS\Parameters\ConfigIsolationPath"
echo You also have to reset the PathWWWRoot and PathFTPRoot registry values
echo in HKEY_LOCAL_MACHINE\Software\Microsoft\InetStp.
echo ===============================================================================
echo.
echo.
endlocal
goto success
REM error message if no argument or drive does not exist
:err
echo.
echo New root drive letter required.
echo Here an example how to move the IIS root to the F:\ drive:
echo.
echo MOVEIISROOT.BAT F
echo.
echo.
:success
REM----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Just copy the above code and save it a .BAT file (eg: MoveIISROOT.bat). Run this command on the server on which the IIS has to be migrated to a non-system drive. Syntx for the command as follows (MoveIISRoot.bat <Destination Drive>):
D:\>MoveIISRoot.bat D
Here D$ will be the new drive on which the IIS will be migrated. The above script will take care of migrating the data (folders), logs and does the configuration changes (registry keys, system cofig etc...)
So, go ahead and use the script to migrate IIS (inetpub and its contents) to any drive on your web server.
"Happy Migrating :-) "
Note: Please restart IIS post migration and also check your websites if they are pointing to the right web folders (if not, update the web folder location. This shouldnt cause any issues as such).
Comments
Anonymous
May 14, 2010
Cool post. Worked like a charm for us in a production scenario. No issues observed after migration. Good Job.Anonymous
May 15, 2010
This is great automation and real time imlplementation at the enterprise scale. However, I wonder why Windows 2008 defaults the inetpub to system drive in the first place. At least for Enterprise Licenses it should not allow webroot on system drive.Anonymous
July 30, 2010
The script has a bug: REM Make sure Service Pack and Hotfix Installers know where the IIS root directories are reg add HKLMSoftwareMicrosoftinetstp /v PathWWWRoot /t REG_SZ /d %mOVETO%inetpubwwwroot /f reg add HKLMSoftwareMicrosoftinetstp /v PathFTPRoot /t REG_SZ /d %MOVETO%inetpubftproot /f The above lines should be : reg add HKLMSoftwareMicrosoftinetstp /v PathWWWRoot /t REG_SZ /d %MOVETO%inetpubwwwroot /f reg add HKLMSoftwareMicrosoftinetstp /v PathFTPRoot /t REG_SZ /d %MOVETO%inetpubftproot /f Note the extra slash after the %MOVETO% variable for 64 BIT registry keys. The extra slash creates registry keys that look like this: F:\inetpubftproot F:\inetpubwwwroot When I installed SharePoint my IIS 7 SharePoint website physical path properties had double slashes after the drive letter and colon and I got 404 errors until I removed the extra slash.