Migrate an IIS Website to a New Server

Here is the situation. I’m running an internal IIS server with a simple website and an FTP website on Windows Server 2008 R2. Of course, Windows Server 2008 is End of Service so we need to migrate the server to a new supported server. Unfortunately, the FTP server contains allot of folders and files with the necessary configurations and permissions. While there are some websites explaining this process, most of them are outdated or are missing some extra information to help you in the process. So, for this reason I found it interesting to write a small tutorial.

Let’s start with the basics. The source server is running Windows Server 2008 R2 and the destination server is running Windows Server 2019. The partition layout of both servers are the same, e.g. the FTP website is hosted on the D-drive. One PRO-tip: Prior to migrating the website the final machine, I first did a test on a VM in Azure.

Install Web Deploy 3

First, start by installing the “Web Deploy 3”-tool of Microsoft on both servers. Unfortunately, this is mandatory and I could not find a way to do it without this tool. The latest version I could find was 3.6 from 2017 and can be found on the website of Microsoft.

Once installed, you can find the command msdeploy under the folder: c:\Program Files\IIS\Microsoft Web Deploy V3

Installing Microsoft Web Deploy is straight forward Next>, Next>, Next>, …

Collect dependencies

Next up is collecting the dependencies on both servers. As this is a 1:1 migration you need to take the dependencies of the full website, using the webServer as source parameter.

On the source server:

msdeploy -verb:getDependencies -source:webServer > c:\Resources\SourceServer.txt

On the destination server:

msdeploy -verb:getDependencies -source:webServer > c:\Resources\DestinationServer.txt
Old school cmd window

Fix missing dependencies

Simply compare both files and make sure you have installed all required roles and features from IIS on the destination server. Be careful in case the server is in production. Again, I have performed this task first on a test VM in Azure. Also look out for dependencies that might have shifted a row lower or higher.

Comparing SourceServer.txt and DestinationServer.txt in Visual Code

Make a backup of original config on Destination Server

⚠ Important: if the migration should fail, you can perform a rollback with these files. So, it is important to have this kind of backup. During my test deployment I initially broke the installation and forgot to back up the original config.

On the destination server:

%windir%\system32\inetsrv\appcmd add backup "BackupName"

Export the website

Let’s start the migration. First perform an export of the full website on the source server. An encryption password is mandatory in this case and to keep it easy I used MyPassKey. I also redirect the output to a log file as this command generated ALLOT of output.

On the source server:

msdeploy -verb:sync -source:webServer -dest:package=C:\Resources\WebsiteExport.zip,encryptPassword=MyPassKey > C:\Resources\WebsiteExport.log

After the export is finished, it’s best to check the log file for any errors and fix them if needed.

Optional: change settings from the website

While it is not recommended, you can make some setting changes to the website package by modifying the archive.xml file inside the package. In my case I needed to change some binding settings, so I extracted the archive.xml file, did the changes and added the file again to the zip-file. Again, I can’t point out how important it is to first perform the migration on a test VM.

Optional: Perform a dry run on the Destination Server

You can perform a dry run easily with the -whatif parameter.

On the destination server:

msdeploy -verb:sync -source:package=C:\Resources\WebsiteExport.zip,encryptPassword=MyPassKey -dest:webServer -whatif > C:\Resources\WebsiteImport-DryRun.log

Import the website

Assuming you couldn’t find any breaking errors in the log file, you can simply import the package on the destination server by removing the -whatif parameter from the command.

On the destination server:

msdeploy -verb:sync -source:package=C:\Resources\WebsiteExport.zip,encryptPassword=MyPassKey -dest:webServer > C:\Resources\WebsiteImport.log

And that’s it. You should now have successfully migrated an IIS website.

Two dry runs and one import later


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.