What it is
Most organisations have a few servers nobody wants to touch. They run an old version of Windows Server, they host a dozen IIS sites, and at least one application depends on a runtime that stopped getting security fixes some time ago. Moving them is not difficult in principle. It goes wrong in the detail.
This is daily work for me in large enterprise estates: server-by-server inventories, app-pool and binding audits, certificate checks, cutover blocker lists, rollback plans and runbooks.
Why migrations go wrong
Almost never because of the new platform. Almost always because of something on the old one that nobody wrote down:
- A site binding for a hostname that still has live traffic, missed because it was not in the change ticket.
- An application pool running as a service account whose password nobody has.
- A certificate installed on the old server and nowhere else, with no record of where it came from.
- A connection string, a file path or a scheduled task that points at the old machine by name.
- One application on a runtime the new server does not support, found on the night.
- A cutover plan with no rollback, because rollback was assumed rather than rehearsed.
How I do it
- Inventory, server by server. Every site, binding, application pool, identity, certificate, scheduled task, service and share. Collected from the server itself, not from memory.
- Map the dependencies. Databases, file shares, other servers, external services, and anything that calls in from outside.
- Write the cutover blocker list. Each item that would stop a clean move, with an owner and a resolution. Nothing moves until that list is empty or every item has an accepted workaround.
- Choose the target honestly. A supported Windows Server, modern .NET on Linux, containers, or retirement. The right answer differs per application.
- Rehearse. Stand up the target, move a copy, test it with the people who use it.
- Test the rollback. Actually go back, on purpose, before the real night. A rollback that has never been run is a hope, not a plan.
- Cut over to the runbook. Every step, every check, every decision point, written so that someone other than me can carry it out.
- Watch, then decommission. The old server stays available for an agreed period before it is switched off.
What you get
- A complete inventory of each legacy server, in a form you can keep.
- The cutover blocker list, with every item resolved or accepted in writing.
- A runbook for each cutover, including the rollback, that a colleague can follow at 2am without phoning me.
- Evidence the rollback was tested.
- Applications running on a supported platform, and the old servers switched off.
Why I can do this
Twenty-plus years in enterprise infrastructure, much of it on exactly these platforms. The method above is not borrowed from a framework. It is the list of things that have gone wrong, turned into steps that stop them going wrong again.
Questions people ask
Does it have to move to Linux?
No. A currently supported Windows Server is often the right answer, particularly for software that only runs on Windows. Modern .NET runs well on both. I recommend per application, not by preference.
Can it be done without downtime?
Sometimes. The inventory tells us which applications can move behind the scenes and which need a maintenance window. You know which is which before anything is scheduled.
What is a cutover blocker?
Anything that would stop a clean move or force a rollback: a missing credential, an unsupported runtime, an undocumented dependency, a certificate with no source. Finding them in advance is most of the work.
We have an application nobody understands. Can it move?
Usually. It gets inventoried like everything else, and sometimes the honest finding is that it should be retired rather than moved.