🚀 Overview
An in-place upgrade allows you to move a Windows Server VM to a newer version of the OS while preserving applications, settings, and data — without rebuilding the machine from scratch. On Azure, this is achieved by attaching a special upgrade media managed disk sourced from the Azure Marketplace and running setup.exe inside the VM.
This guide covers the end-to-end process for upgrading an Azure-hosted Windows Server VM to Windows Server 2022 or 2025, including pre-flight checks, disk management, snapshot protection, PowerShell automation, and post-upgrade validation.
✅ Step 1–3: Prerequisites & Volume Licensing
Validate Volume Licensing
Before starting an in-place upgrade, confirm that the VM is running a volume-licensed edition of Windows Server. If the VM was imported or migrated into Azure from an on-premises environment, it may need to be converted to volume licensing before the Azure upgrade media will work.
Check activation status inside the VM
slmgr /dlv
Look for Volume:MAK or Volume:KMS in the output. If it shows Retail, the VM needs converting first.
Install Generic Volume License Key (if required)
If the VM is not already volume-licensed, install the appropriate Generic Volume License Key (GVLK) from the
Microsoft KMS client activation keys page before proceeding.
# Example: Install GVLK for Windows Server 2019 Standard
slmgr /ipk WMDGN-G9PQG-XVVXX-R3X43-63DFG
# Activate against KMS
slmgr /ato
💾 Step 4–6: Disk Resizing
Check Minimum Disk Space Requirement
According to Microsoft's hardware requirements, a Windows Server in-place upgrade requires a minimum of 32 GB free space on the OS drive. Verify the current free space inside the VM before continuing.
⚠️ Important: If the OS disk does not have at least 32 GB of free space, you must resize the disk before the upgrade. The setup process will abort if this requirement is not met.
Azure Premium SSD Disk Tiers
Azure Premium SSD disks are billed and provisioned at fixed tier sizes. A common scenario is upgrading from a P6 (64 GiB) disk to a P10 (128 GiB) disk to meet the space requirement:
| Disk Tier | Size | IOPS | Throughput | Meets 32 GB req? |
| P6 | 64 GiB | 240 | 50 MB/s | ❌ Only if OS footprint is very small |
| P10 | 128 GiB | 500 | 100 MB/s | ✅ Yes |
| P15 | 256 GiB | 1,100 | 125 MB/s | ✅ Yes |
| P20 | 512 GiB | 2,300 | 150 MB/s | ✅ Yes |
ℹ️ Note: P6 = 64 GiB and P10 = 128 GiB are confirmed Azure Premium SSD tier sizes.
Whether a P6 disk has enough free space for an upgrade depends entirely on how much of the 64 GiB is already used by the OS and applications.
If you have less than 32 GB free, resize to P10 (128 GiB).
Steps to Resize the OS Disk
- Power off the VM from the Azure portal (Deallocated state)
- Navigate to the VM → Disks → click the OS disk name
- Select Size + performance and choose the new disk size (e.g., 128 GiB)
- Click Save and wait for the resize to complete
- Power on the VM
- Inside the VM, open Disk Management, right-click the C: partition, and choose Extend Volume to claim the new unallocated space
Managed Disks Check
Verify the VM is using Managed Disks (visible in the VM's Disks blade — it will show a disk SKU such as Premium SSD LRS). Modern Azure VMs use managed disks by default, so no conversion is typically needed.
📸 Step 7–8: Snapshot & Boot Diagnostics
Enable Boot Diagnostics
Boot diagnostics lets you monitor the VM's screen output through the Azure portal — essential for tracking upgrade progress after RDP disconnects.
- With the VM powered off, go to Settings → Boot diagnostics
- Select "Enable with managed storage account (recommended)"
- Save the setting
Create a Full OS Disk Snapshot
Always take a snapshot of the OS disk before the upgrade. This is your rollback point if anything goes wrong.
- Go to the VM → Disks → click the OS disk
- Click "Create snapshot"
- Choose snapshot type: Full
- Set the Subscription, Resource group, and Storage type (Standard HDD LRS is fine for backup snapshots — cost-effective)
- Click Review + Create and confirm the snapshot was created successfully
- Power the VM back on
💡 Pro Tip: Keep the snapshot until you — and any stakeholders — have confirmed the upgrade is fully successful and all applications are running correctly. Only delete it once you have sign-off.
What is the Upgrade Media Disk?
Azure hosts special hidden VM images in the Marketplace that contain the Windows Server upgrade installer. The process is to pull the latest version of this image and create a Managed Disk from it, which is then attached to your VM like a data disk. The VM's setup.exe on that disk drives the upgrade.
PowerShell Script — Run in Azure Cloud Shell
Open Azure Cloud Shell (PowerShell) and run the script below. Update the variables at the top to match your environment before executing.
#
# Customer specific parameters
# Resource group of the source VM
$resourceGroup = "WindowsServerUpgrades"
# Location of the source VM
$location = "WestUS2"
# Zone of the source VM, if any
$zone = ""
# Disk name for the that will be created
$diskName = "WindowsServer2025UpgradeDisk"
# Target version for the upgrade - must be one of these five strings: server2025Upgrade, server2022Upgrade, server2019Upgrade, server2016Upgrade or server2012Upgrade
$sku = "server2025Upgrade"
# Common parameters
$publisher = "MicrosoftWindowsServer"
$offer = "WindowsServerUpgrade"
$managedDiskSKU = "Standard_LRS"
#
# Get the latest version of the special (hidden) VM Image from the Azure Marketplace
$versions = Get-AzVMImage -PublisherName $publisher -Location $location -Offer $offer -Skus $sku | sort-object -Descending {[version] $_.Version }
$latestString = $versions[0].Version
# Get the special (hidden) VM Image from the Azure Marketplace by version - the image is used to create a disk to upgrade to the new version
$image = Get-AzVMImage -Location $location -PublisherName $publisher -Offer $offer -Skus $sku -Version $latestString
#
# Create Resource Group if it doesn't exist
#
if (-not (Get-AzResourceGroup -Name $resourceGroup -ErrorAction SilentlyContinue)) {
New-AzResourceGroup -Name $resourceGroup -Location $location
}
#
# Create managed disk from LUN 0
#
if ($zone){
$diskConfig = New-AzDiskConfig -SkuName $managedDiskSKU -CreateOption FromImage -Zone $zone -Location $location
} else {
$diskConfig = New-AzDiskConfig -SkuName $managedDiskSKU -CreateOption FromImage -Location $location
}
Set-AzDiskImageReference -Disk $diskConfig -Id $image.Id -Lun 0
New-AzDisk -ResourceGroupName $resourceGroup -DiskName $diskName -Disk $diskConfig
Script Variables Reference
| Variable | Description | Example |
$resourceGroup | Resource group for the upgrade disk (created if absent) | WindowsServerUpgrades |
$location | Azure region — must match the target VM's region | WestUS2, UK South |
$zone | Availability zone; leave empty if VM is not zone-pinned | "" or "1" |
$diskName | Name for the new upgrade media disk | WindowsServer2025UpgradeDisk |
$sku | Target Windows Server version | server2025Upgrade · server2022Upgrade · server2019Upgrade · server2016Upgrade · server2012Upgrade |
$managedDiskSKU | Storage tier for the upgrade disk | Standard_LRS · Premium_LRS |
🔗 Step 11: Attach Upgrade Media to the VM
Once the upgrade media disk has been created, attach it to the target VM. The VM can be running or stopped during this step.
- In the Azure portal, navigate to Virtual Machines and select the VM to upgrade
- Go to Settings → Disks
- Click "Attach existing disks"
- In the Disk name dropdown, select the upgrade media disk you just created
- Click Save
ℹ️ Drive letter: Once the VM is running, the upgrade disk typically appears as drive E: (assuming no other data disks are attached). Confirm this inside the VM before running setup.exe.
🖥️ Step 12–13: Perform the In-Place Upgrade
Pre-flight Checklist
Before running setup.exe, confirm:
- VM is in Running state
- Upgrade media disk is attached and visible in File Explorer
- OS disk has ≥ 32 GB free space
- Boot diagnostics is enabled
- You have RDP access with an administrator account
Run the Upgrade
- RDP into the VM using an administrator account
- Open File Explorer and note the drive letter of the upgrade disk (typically E:)
- Open PowerShell as Administrator
- Navigate to the upgrade disk root:
cd E:\
- Start the upgrade:
.\setup.exe /auto upgrade /dynamicupdate disable
⚠️ Do not interrupt: Once setup.exe begins, the VM will restart multiple times automatically. Your RDP session will disconnect — this is expected. Do not force-restart or shut down the VM while the upgrade is in progress.
📊 Step 14–15: Monitor via Boot Diagnostics
After your RDP session drops, switch to the Azure portal to monitor progress:
- Go to the VM → Help → Boot diagnostics → Screenshot
- Refresh every 5–10 minutes to watch the upgrade progress screens
- Expect to see phases such as: Copying files, Installing features, Installing updates, Finalising, and then the Windows login screen
| Phase | Approx. Duration | What to Expect |
| File copy & preparation | 10–20 min | Progress percentage on screen |
| Pre-upgrade compatibility checks | 5–10 min | Automated compatibility scan |
| OS installation | 30–45 min | File replacement, component updates |
| Automatic restarts | 10–20 min | Multiple reboots — all expected |
| Total | ~1–2 hours | Windows login screen signals completion |
✅ Step 16–17: Post-Upgrade Validation
Verify the Windows Server Version
# Run inside the VM via RDP or Azure Run Command
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" `
-Name ProductName, CurrentBuildNumber
Check Automatic Services
# Find any Automatic services that are Stopped
Get-Service | Where-Object { $_.StartType -eq 'Automatic' -and $_.Status -eq 'Stopped' } |
Select-Object Name, DisplayName, Status
Install Latest Windows Updates
After confirming the version upgrade was successful, install all available Windows updates to bring the server fully up to date:
- Settings → Update & Security → Windows Update → Check for updates
- Install all available patches and restart if prompted
- Re-run Windows Update until no further updates are available
Application & Service Validation
✅ Post-upgrade checklist
- Confirm all business-critical services and applications are running
- Check Windows Event Viewer for any critical errors
- Validate network connectivity (DNS, domain membership, firewall rules)
- Test all application functionality end-to-end
- Notify relevant teams (e.g. monitoring, network) to validate their integrations
🧹 Step 18: Cleanup
Once the upgrade is confirmed as successful by all stakeholders:
- Detach the upgrade media disk from the VM (VM → Disks → select the upgrade disk → Detach → Save)
- Delete the upgrade media disk from the Azure portal to stop billing
- Delete the pre-upgrade snapshot once sign-off is received — do not delete it prematurely
⚠️ Snapshot retention: Keep the pre-upgrade snapshot until you have explicit confirmation from the application owner or stakeholders that everything is working correctly post-upgrade. It is your only rollback point.
🐛 Troubleshooting Common Issues
| Symptom | Likely Cause | Resolution |
| Setup aborts with "Not enough space" |
OS disk has less than 32 GB free |
Resize the disk (P6 → P10 or larger) and extend the volume before re-running |
| Setup.exe not found on upgrade disk |
Wrong drive letter assumed |
Open File Explorer and find the drive that contains setup.exe at its root |
| Boot diagnostics screenshot doesn't change |
Upgrade is processing (IO intensive) |
Wait at least 60–90 min before assuming a hang; do not restart the VM |
| VM offline after upgrade |
Final reboot still in progress |
Wait 10–15 minutes; check Boot Diagnostics; verify VM shows Running in portal |
| KMS activation fails post-upgrade |
Volume license key needs refreshing |
Run slmgr /ato inside the VM to re-trigger KMS activation |
💡 Best Practices
- Always test in non-production first — validate the exact same upgrade path on a dev or test VM before touching production
- Schedule a maintenance window — the upgrade takes 1–2 hours with application downtime
- Take a snapshot before you start — it is your only rollback option
- Use Boot Diagnostics — enable it before the upgrade so you can monitor without RDP
- Disable Dynamic Update — the
/dynamicupdate disable flag prevents the setup from reaching out to Windows Update mid-upgrade, which keeps the process deterministic
- Keep stakeholders informed — communicate at each milestone: snapshot taken, upgrade started, upgrade complete, validation done
- Patch immediately after upgrading — run Windows Update fully before handing back to users
📦 GitHub
The PowerShell script used in this guide is published in the Azure automation repository. Clone it, update the variables to match your environment, and run it directly from Azure Cloud Shell.
View on GitHub →
Azure
Windows Server
PowerShell
Managed Disks
In-Place Upgrade
Windows Server 2022
Windows Server 2025
KMS Licensing
Boot Diagnostics