In this guide, we will show you step-by-step how to perform in-place upgrade Windows Server VMs running in Microsoft Azure.
Table of Contents
Introduction
The process of upgrading to a newer version of Windows Server can vary greatly, depending on which operating system you are starting with and the pathway you take.
The upgrade is also known as an “in-place upgrade”, where you move from an older version of the operating system to a newer version while staying on the same virtual or physical hardware.
Since Windows Server 2016, Microsoft announced support for in-place upgrades for standalone installation, as well as for Windows Server with clusters (known as Cluster OS Rolling Upgrades) installed on-premises and not in Azure.
However, for older Windows Server operating systems running in Microsoft Azure, it was a pain to perform an in-place upgrade. To overcome this unsupported scenario, we used to go through the long workaround documented by Microsoft of downloading the VHD from Azure, performing an in-place upgrade in a local Hyper-V server, and then uploading the VHD to Azure.
I was involved recently in performing multiple Windows Servers upgrades in Microsoft Azure, and I am happy to see that Microsoft recently announced the in-place upgrade for VMs running Windows Server in Azure.
This guide will walk you through each step on how to move your Azure VMs to a later version of Windows Server using an in-place upgrade.
Prerequisites
Before you start with the in-place upgrade of your VMs running the Windows Server in Azure, you need to verify the following prerequisites:
1) Azure subscription – If you don’t have an Azure subscription, you can create a free one here.
2) At the time of this writing, the following source and target operating systems are supported for the in-place upgrade:
Upgrade from | Upgrade to |
---|---|
Windows Server 2012 R2 (Core) | Windows Server 2019 (Core) |
Windows Server 2012 R2 | Windows Server 2019 (Desktop Experience) |
Windows Server 2016 (Core) | Windows Server 2019 (Core) -or- Windows Server 2022 (Core) |
Windows Server 2016 (Desktop Experience) | Windows Server 2019 (Desktop Experience) -or- Windows Server 2022 (Desktop Experience) |
Windows Server 2019 (Core) | Windows Server 2022 (Core) |
Windows Server 2019 (Desktop Experience) | Windows Server 2022 (Desktop Experience) |
3) The following operating systems are not supported for the in-place upgrade. You must go through the manual workaround described here.
- Windows Server 2012.
- Windows Server 2008.
4) Verify the operating system disk has enough free space to perform the in-place upgrade. You need at least 32 GB free (an absolute minimum) for a successful installation. If you need additional space, you can expand and resize the virtual hard disks attached to your Windows virtual machine before you start.
5) Disable temporarily any antivirus, anti-spyware software, and firewalls that you have on the machine.
6) If you still have Microsoft Silverlight installed on your old Windows Server machine, make sure it’s removed. Microsoft Silverlight reached the end of support on October 12, 2021.
7) The source VM that you want to upgrade, must be using Managed Disk. If the VM is still using Unmanaged disks, then check the following steps to migrate the VM to Managed Disks using PowerShell.
8) Last, make sure the VM is using a volume license because the upgrade media provided by Azure, requires the VM to be configured for Windows Server volume licensing. This is the default for any Windows Server VMs created on Azure. However, if your VM was migrated to Azure using Azure Migrate or Azure Site Recovery, then you will need to upgrade/convert the VM to a volume license.
To confirm if the VM is configured for volume license activation, you can run the following command:
cscript c:\windows\system32\slmgr.vbs /dlv

Now, if the command above shows a RETAIL channel, then you need to run the following commands to set the KMS client setup key for the version of Windows Server being used, and force it to retry activation:
cscript c:\windows\system32\slmgr.vbs /ipk <KMS client setup key>
cscript c:\windows\system32\slmgr.vbs /ato
Next, make sure that the Azure VM is configured to use the correct Azure KMS server. To do this, you can run the following command:
Invoke-Expression "$env:windir\system32\cscript.exe $env:windir\system32\slmgr.vbs /skms kms.core.windows.net:1688"
You should see, the Key Management Service machine name set to kms.core.windows.net:1688 successfully, as shown in the figure below:

In-Place Upgrade Windows Server in Azure
Once you’ve verified that all prerequisites noted above, you can proceed with the following steps:
Step 1) Create a snapshot of the OS disk
Microsoft recommends that you create a snapshot of your operating system disk and any data disks before starting the in-place upgrade process. A snapshot is a full, read-only copy of a virtual hard disk (VHD).
This step absolutely makes total sense, because this will enable you to revert to the previous state of the VM if anything fails during the in-place upgrade process. And trust me, you might face this issue.
First, you need to ensure that you cleanly shut down the VM in Azure.
To create a snapshot of a virtual hard disk using Azure PowerShell, run the following commands:
First, you’ll use the New-AzSnapshotConfig cmdlet to create a configurable snapshot object. You can then use the New-AzSnapshot cmdlet to take a snapshot of the disk.
Set the required parameters below. Update the values below to reflect your environment.
$resourceGroupName = 'ResourceGroupName'
$location = 'westeurope'
$vmName = 'AzureVM12R2'
Next, use the Get-AzVM cmdlet to get the VM containing the VHD you want to copy:
$vm = Get-AzVM `
-ResourceGroupName $resourceGroupName `
-Name $vmName
Next, you need to create the snapshot configuration. In the example below, the snapshot is for the OS disk:
$osSnapshot = New-AzSnapshotConfig `
-SourceUri $vm.StorageProfile.OsDisk.ManagedDisk.Id `
-Location $location `
-CreateOption copy
Now by default, the snapshot uses locally redundant standard (LRS) storage (-AccountType StandardLRS). This is the recommended option to store your snapshots in standard storage instead of premium storage because premium snapshots will incur additional costs.
Last but not least, take a snapshot of the OS Disk by running the following command:
$snapshotOsName = "$($vm.StorageProfile.OsDisk.Name)_Snapshot_$(Get-Date -Format dd_MM_yyyy)"
New-AzSnapshot `
-Snapshot $osSnapshot `
-SnapshotName $snapshotOsName `
-ResourceGroupName $resourceGroupName

Now if your VM has Data disks, then you can use the PowerShell script below to create the snapshot configuration for all of your data disks.
$dataDisks = ($vm.Storageprofile.DataDisks).name
foreach ($datadisk in $datadisks) {
$dataDisk = Get-AzDisk -ResourceGroupName $resourceGroupName -DiskName $datadisk
Write-Output "VM $($vm.name) data Disk $($datadisk.Name) Snapshot Begin"
$DataDiskSnapshotConfig = New-AzSnapshotConfig -SourceUri $dataDisk.Id -CreateOption Copy -Location $location
$snapshotDataName = "$($datadisk.name)_snapshot_$(Get-Date -Format dd_MM_yyyy)"
New-AzSnapshot -ResourceGroupName $resourceGroup -SnapshotName $snapshotDataName -Snapshot $DataDiskSnapshotConfig -ErrorAction Stop
Write-Output "VM $($vm.name) Data Disk $($datadisk.Name) Snapshot End"
}
Last, you can use the Get-AzSnapshot cmdlet to verify that your snapshot exists:
Get-AzSnapshot `
-ResourceGroupName $resourceGroupName
Step 2) Create an upgrade media disk
Next, you have to create what’s known as an upgrade media disk. The upgrade media disk must be attached to the source VM that you intend to upgrade as a Managed Disk.
You can find more on how to create an upgrade media disk using PowerShell as documented officially by Microsoft here.
In my case, we need to create the upgrade media for Windows Server 2019. So we need to modify the variables in the PowerShell script to target either Windows Server 2022 or Windows Server 2019.
Here is an example of the condensed PowerShell script that will create an upgrade media disk for Windows Server 2019:
# Upgrade Disk name that will be created
$upgradeDiskName = "WindowsServer2019UpgradeDisk"
# Target version for the upgrade - must be either server2022Upgrade or server2019Upgrade
$sku = "server2019Upgrade"
# 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 Managed Disk from LUN 0
$diskConfig = New-AzDiskConfig -SkuName $managedDiskSKU `
-CreateOption FromImage `
-Location $location
Set-AzDiskImageReference -Disk $diskConfig -Id $image.Id -Lun 0
New-AzDisk -ResourceGroupName $resourceGroupName `
-DiskName $upgradeDiskName `
-Disk $diskConfig

Step 3) Attach the upgrade media to the VM
Next, we need to attach the newly created media-managed disk to the source VM.
Of course, this step can be done using the Azure portal, CLI, PowerShell, or the REST API.
In this example, we will use the following PowerShell commands to attach the upgrade media disk. Update the values below to reflect your environment:
$resourceGroupName = 'ResourceGroupName'
$vmName = 'AzureVM12R2'
$location = 'westeurope'
$storageType = 'Standard_LRS'
$upgradeDiskName = "WindowsServer2019UpgradeDisk"
$upgradeDataDisk = Get-AzDisk -DiskName $upgradeDiskName -ResourceGroupName $resourceGroupName
$vm = Get-AzVM -Name $vmName -ResourceGroupName $resourceGroupName
$vm = Add-AzVMDataDisk -VM $vm -Name $upgradeDiskName -CreateOption Attach -ManagedDiskId $UpgradeDataDisk.Id -Lun 0
Update-AzVM -VM $vm -ResourceGroupName $resourceGroupName

Step 4) Perform an in-place upgrade
In the last step, you perform the in-place upgrade as you would normally do.
First, you must connect to the Azure VM by using Azure Bastion, RDP over ExpressRoute, or Site-to-Site/Point-to-Site VPN. Public RDP is not recommended for security reasons.
Once you connect to the VM, you need to bring the attached upgrade media disk Online.

Check the drive letter for the upgrade disk (typically E: or F: if there are no other data disks attached to the VM).
Get-Volume | Where FileSystemLabel -eq 'upgrade'

Next, change the directory to the only directory (Windows Server 2019 or Windows Server 2022) on the upgrade disk, and then run the following command to kick off the upgrade process.
.\setup.exe /auto upgrade /dynamicupdate disable

Then make sure to select the correct “Upgrade to” image based on the current version and configuration of the VM that you want to upgrade using the following table:
Upgrade from | Upgrade to |
---|---|
Windows Server 2012 R2 (Core) | Windows Server 2019 (Core) |
Windows Server 2012 R2 | Windows Server 2019 (Desktop Experience) |
Windows Server 2016 (Core) | Windows Server 2019 (Core) -or- Windows Server 2022 (Core) |
Windows Server 2016 (Desktop Experience) | Windows Server 2019 (Desktop Experience) -or- Windows Server 2022 (Desktop Experience) |
Windows Server 2019 (Core) | Windows Server 2022 (Core) |
Windows Server 2019 (Desktop Experience) | Windows Server 2022 (Desktop Experience) |

Now during the in-place upgrade process, the VM will automatically disconnect from the RDP session. After the VM is disconnected from the RDP session, you can monitor the upgrade process through the Boot diagnostics screenshot functionality available in the Azure VM blade.

That’s it there you have it!
Post Upgrade Cleanup
Once the upgrade process has been completed successfully, make sure to take the following steps to clean up any artifacts which were created during the in-place upgrade process:
- Delete the snapshots of the OS disk and data disk(s) if they were created.
- Delete the upgrade media Managed Disk.
- Enable any antivirus, anti-spyware, or firewall software that may have been disabled at the start of the upgrade process.
Summary
In this article, we showed you to move from an older Windows Server operating system to a newer one using an in-place upgrade, while keeping your settings, server roles, and data intact.
It is great to see that Microsoft supports now in-place upgrade for Windows Server on Microsoft Azure instead of going through the long workaround of downloading the VHD from Azure, performing an in-place upgrade in a local Hyper-V server, and then uploading the VHD to Azure.
This is so much faster and more efficient.
Learn more: 5 Critical Best Practices to hardening your Azure VMs.
__
Thank you for reading my blog.
If you have any questions or feedback, please leave a comment.
-Charbel Nemnom-