Don’t do it! Ok, do it, but only if it is really necessary. (You will probably run into a lot of problems!)

Our old server started to get old. The processor chip, RAM and HDD was outdated. We ordered a new server which is faster, has more RAM and a SSD. On our new server Monitoring is faster, TeamCity configurations run faster, web sites are being delivered faster, and the server UI is much more responsive. In the end the server change was good, but the move took quite some time!

We moved from a Windows Server 2008 R2 with IIS 7.5 to a Windows Server 2012 R2 with IIS 8.5.

Approach One: move data and configuration separately

This did not work for me this time. You copy all the data in the wwwroot directory to the new server. Then you export the IIS configuration on the old server and import it on the new server. There are a few blog posts talking about this. But you may corrupt your IIS configuration like I did. Make sure to backup the initial configuration to be able to restore it. IIS also has a history itself (C:\inetpub\history). If all fails you will have to uninstall the IIS feature and install it anew.

Approach Two: move data and configuration together

You can use Web Deploy to move all your sites and their IIS configuration to the new server (needs to be installed on both servers). I first tried it using the UI, but always ran into problem when importing. Command line syntax to the rescue! It gave me better error feedback. The command I used at the end:

C:\Program Files\IIS\Microsoft Web Deploy V3>msdeploy.exe -verb:sync -source:package=C:\_backups\IIS\IIS_PA1.zip,machineconfig32.netfxversion=2,machineconfig64.netfxversion=2,rootwebconfig32.netfxversion=2,rootwebconfig64.netfxversion=2,encryptPassword=teamaton -dest:webserver,machineconfig32.netfxversion=2,machineconfig64.netfxversion=2,rootwebconfig32.netfxversion=2,rootwebconfig64.netfxversion=2

Here you can read more about the sync verb, provider package and webserver, and encryptPassword.

Here are the problems I ran into, and how I circumvented them:

  • Dynamic IP Restrictions module is an extension in IIS 7.5, but a feature in IIS 8.5 (Web Server –> Security –> “IP and Domain Restrictions”). Therefore I needed to uninstall the extension on IIS 7.5 and only then export with Web Deploy.
  • Frameworks do not match: "The versions of the .NET Framework Configuration Provider (machineConfig64) are different on the source (2.0) and destination (4.0)." Phu, this was a tough one – I tried very many things unsuccessfully. In the end I used option 1 in this article, because option 2 never worked – even though most proposed solutions on the internet use this option 2.
  • Then I ran into the error 0x800f0922 which I fixed with this solution.
  • As usual I ran into the error “Service unavailable” after the import. This is usually an indicator that some feature is missing in the IIS. I needed to install the URL Rewrite Module.
  • A few DLLs were missing on the target machine. I had to compare the machine.configs and adjust them as needed.

Problems with WordPress web site

First I tried to transfer the WordPress blog like the other sites. Move its IIS configuration, the wwwroot folder and its MySQL database. That did not give me the desired result, and gave me quite a few headaches:

  • Web Deploy makes changes to .NET Framework config files (for instance machine.config and web.config) – I had to copy them from other server.
  • Using the PHP Manager for IIS did not help.
  • FastCGI could not be loaded because of version problems.

Probably the best way to migrate a WordPress site is using the Duplicator extension. Just two caveats: you will need to give USERS folder rights (other sites usually need rights to be given to IIS_IUSRS). And “Select Advanced Options and select the manual unzip process“ should be done in step 1 of “Run the Duplicator Installer”.

Migrate SQL databases

We migrated from SQL Server 2008 to SQL Server 2014. First thing I forgot was to ensure that the new instance is installed with “Mixed Authentication” (it allows Windows + SQL logins). I copied the databases according to this article. I only changed the level to 120, which corresponds to SQL Server 2014. Then I had to copy users with their passwords. I did it by creating a procedure.

One of our TeamCity configurations runs unit tests based on Entity Framework 6.0. It need to be able to create a database on the fly, but I always got System.Data.SqlClient.SqlException : CREATE DATABASE permission denied in database 'master'. Turns out the login NT AUTHORITY\SYSTEM needs the dbcreator Server Role.