Migrating IIS Bindings Between Windows VPS Hosts

Migrating IIS Bindings Between Windows VPS Hosts

Close-up of circuit board traces suggesting web server infrastructure

TL;DR: Moving sites between Windows guests is less about copying inetpub and more about reconciling bindings, certificates, app pools, and DNS cutover. Export configuration, verify hostname and SNI bindings on the new Windows VPS, then flip DNS only after HTTPS responds on the destination IP.

Inventory before you touch DNS

List every site in IIS Manager or via Get-Website and Get-WebBinding. Capture host headers, ports, IP assignments (or “All Unassigned”), and whether SNI is required. Screenshot or export certificate thumbprints tied to each https binding. Note app pool identities, .NET CLR versions, and any URL Rewrite rules that hard-code old hostnames.

Also capture non-IIS dependencies: scheduled tasks that hit local sites, Windows services posting to localhost, and firewall rules for custom ports. Migrations fail late when a background worker still targets the old machine name.

Move content and config as separate streams

Robocopy or package the site folders first, preserving ACLs for the app pool identity. Separately export IIS config with appcmd list site /config /xml or shared configuration backups. Blindly cloning the entire Windows volume copies secrets and stale HTTP.sys reservations you may not want.

On the destination, create matching folder roots before importing bindings. Importing a site that points at D:\sites\app when only C:\inetpub exists yields mysterious 500.19 errors that look like XML corruption but are simple path misses.

App pool identity friction

ApplicationPoolIdentity creates per-pool virtual accounts. After migration those SIDs differ. Re-ACL the content roots for the new pool identities rather than running everything as LocalSystem “just for today.” If you used custom domain service accounts, confirm the new VPS can reach the domain or switch to local least-privilege users before go-live.

Certificates: export, import, then bind

PFX export from the source (with private key) into the destination Local Computer\Personal store. Bind by thumbprint, not by friendly name—names collide across environments. For Let’s Encrypt style renewals, reinstall the ACME client on the new host and run a staging issuance against a temporary hostname or hosts-file override before production DNS moves.

Central Certificate Store setups need the file share and naming convention recreated; missing CCS paths present as binding failures even when the PFX exists in the personal store.

HTTP.sys URL reservations and port collisions

HttpListener apps and some agents reserve URL prefixes that conflict with IIS. After import, run netsh http show urlacl and netstat -ano for :80/:443. A side-installed panel or old Tomcat service holding 8080 is a classic “site starts but never answers” culprit.

If the source used a dedicated private IP binding, the destination may only have one public address. Convert to host-header + SNI bindings instead of inventing fake secondary IPs in IIS that the hypervisor will never deliver.

Warm the destination while DNS still points at the old box

Edit your workstation hosts file to resolve the public hostname to the new VPS IP. Browse every critical path: home, login, static assets, and one authenticated POST. Check response headers for unexpected redirects to the old IP or http→https loops caused by rewrite rules that assumed the previous load balancer.

Only when hosts-file tests pass should you lower TTL (ideally hours earlier) and update A/AAAA records. Keep the old VPS read-only or on a maintenance page during propagation so dual-write databases do not diverge.

Database connection strings and secret sprawl

Web.config transforms and environment variables often still name the old SQL host. Search the migrated tree for the previous VPS hostname and internal IP. Update connection strings, Redis endpoints, and SMTP relays in one pass, then recycle app pools. Leaving one forgotten API project on the old string creates intermittent bugs that look like “migration flakiness.”

Rollback that is actually usable

Do not delete the source VPS on cutover day. Leave IIS running but remove public publish (panel ACL deny, or stop http/https bindings) so a DNS revert restores service. Document the exact DNS values and the timestamp of the cut. Snapshot both guests before binding imports so a bad appcmd merge is not a rebuild.

Post-cutover binding audit on the new host

Twenty-four hours later, dump bindings again and compare to your pre-migration inventory. Confirm auto-renewal scheduled tasks fired, Windows Firewall still allows 80/443 on the active profile, and that no leftover site still points at empty folders. Watch HTTP.sys error logs for hostname mismatches from clients that cached the old IP.

Decommission the source only after analytics and mail flows look healthy on the destination. A binding-aware migration on windows-vps.org finishes when certificates renew themselves and the old guest is powered off on purpose—not when the first homepage hit merely “looks fine.”