Reference
Masterclassmedium

Plan and Execute Windows Server Upgrades Using Supported Paths

Emanuel DE ALMEIDA
3/13/2026 15 MIN 0 VIEWS

Executive Summary

Master Windows Server in-place upgrades from 2012 R2 to 2025 with proper planning, supported upgrade paths, and step-by-step execution including verification commands.

What are the supported Windows Server upgrade paths in 2026?

Planning a Windows Server upgrade requires understanding Microsoft's supported upgrade paths and following a systematic approach. With Windows Server 2025 now available, Microsoft has expanded in-place upgrade options, allowing jumps of up to four versions in some cases. However, not all upgrade paths are supported, and attempting unsupported upgrades will result in failure.

This comprehensive guide walks you through the entire process, from initial planning to post-upgrade verification, ensuring your server upgrade succeeds without data loss or extended downtime.

How do I determine my current Windows Server version and upgrade options?

Before planning any upgrade, you need to accurately identify your current Windows Server version and understand which upgrade paths are available. Microsoft maintains strict compatibility matrices that determine supported upgrade scenarios.

Start by documenting your current system configuration. Open PowerShell as Administrator and run these commands to capture essential system information:

Get-ComputerInfo -Property WindowsBuildLabEx,WindowsEditionID,TotalPhysicalMemory | Out-File -FilePath C:\Temp\computerinfo.txt
systeminfo.exe | Out-File -FilePath C:\Temp\systeminfo.txt
ipconfig /all | Out-File -FilePath C:\Temp\ipconfig.txt
Get-WindowsFeature | Where-Object InstallState -eq "Installed" | Out-File -FilePath C:\Temp\installed-features.txt

Next, identify your exact Windows Server version:

$OS = Get-WmiObject -Class Win32_OperatingSystem
Write-Host "Current Version: $($OS.Caption)"
Write-Host "Build Number: $($OS.BuildNumber)"
Write-Host "Edition: $($OS.OperatingSystemSKU)"

The upgrade path matrix for 2026 shows significant limitations for older versions:

Source VersionTo 2016To 2019To 2022To 2025
2008/2008 R2NoNoNoNo
2012YesNoNoNo
2012 R2YesYesNoYes
2016N/AYesYesYes
2019N/AN/AYesYes
2022N/AN/AN/AYes
Warning: Windows Server 2008 and 2008 R2 have no supported in-place upgrade paths to modern versions. These systems require complete migration to new hardware with fresh installations.

For systems running Windows Server 2012, you must first upgrade to 2016 before proceeding to newer versions. This creates a multi-step upgrade process that requires additional planning and downtime.

What system requirements must I verify before upgrading Windows Server?

System requirements verification prevents upgrade failures and ensures optimal performance post-upgrade. Windows Server 2025 has specific hardware and software prerequisites that must be met.

Check your system's hardware specifications:

$RAM = [math]::Round((Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum).sum /1gb,2)
$CPU = Get-WmiObject -Class Win32_Processor | Select-Object Name, NumberOfCores, NumberOfLogicalProcessors
$Disk = Get-WmiObject -Class Win32_LogicalDisk -Filter "DriveType=3" | Select-Object Size,FreeSpace

Write-Host "RAM: $RAM GB (Minimum: 2GB for Desktop Experience, 512MB for Core)"
Write-Host "CPU: $($CPU.Name) - Cores: $($CPU.NumberOfCores), Logical: $($CPU.NumberOfLogicalProcessors)"
foreach($Drive in $Disk) {
    $FreeGB = [math]::Round($Drive.FreeSpace /1GB,2)
    $TotalGB = [math]::Round($Drive.Size /1GB,2)
    Write-Host "Drive Space: $FreeGB GB free of $TotalGB GB total (Minimum: 32GB required)"
}

Verify licensing requirements. Windows Server upgrades require valid Software Assurance or equivalent licensing:

$LicenseStatus = Get-CimInstance -ClassName SoftwareLicensingProduct | Where-Object {$_.PartialProductKey -and $_.Name -like "*Windows Server*"}
$LicenseStatus | Select-Object Name, LicenseStatus, GracePeriodRemaining

Check for incompatible software or roles that might block the upgrade:

Get-WindowsFeature | Where-Object InstallState -eq "Installed" | Select-Object Name, InstallState
Get-WmiObject -Class Win32_Product | Where-Object Name -like "*antivirus*" | Select-Object Name, Version
Pro tip: Document all third-party software versions before upgrading. Some applications may require updates or reinstallation after the Windows Server upgrade completes.

How do I prepare my Windows Server system for upgrade?

Proper system preparation significantly reduces upgrade failure risk and ensures faster recovery if issues occur. This phase involves updating the current system, creating backups, and preparing installation media.

Start by installing all available Windows Updates. Outdated systems frequently experience upgrade failures:

Install-Module PSWindowsUpdate -Force -Scope CurrentUser
Import-Module PSWindowsUpdate
Get-WUInstall -AcceptAll -AutoReboot

Create comprehensive system backups using Windows Server Backup:

Import-Module WindowsServerBackup
$Policy = New-WBPolicy
$BackupLocation = New-WBBackupTarget -VolumePath "E:\"
Add-WBBackupTarget -Policy $Policy -Target $BackupLocation
$SystemVolume = Get-WBVolume -VolumePath "C:\"
Add-WBVolume -Policy $Policy -Volume $SystemVolume
Start-WBBackup -Policy $Policy

For virtualized environments, create VM snapshots as an additional safety measure:

# For Hyper-V environments
Checkpoint-VM -Name "YourServerName" -SnapshotName "Pre-Upgrade-$(Get-Date -Format 'yyyy-MM-dd-HHmm')"
# Verify snapshot creation
Get-VMSnapshot -VMName "YourServerName" | Select-Object Name, CreationTime

Download the Windows Server 2025 ISO from the Microsoft Volume Licensing Service Center. Mount and verify the installation media:

$ISOPath = "C:\Downloads\WindowsServer2025.iso"
$MountResult = Mount-DiskImage -ImagePath $ISOPath -PassThru
$DriveLetter = ($MountResult | Get-Volume).DriveLetter
Write-Host "ISO mounted to drive: $DriveLetter"

# Verify setup files
$SetupPath = "${DriveLetter}:\\setup.exe"
if (Test-Path $SetupPath) {
    $FileVersion = (Get-ItemProperty $SetupPath).VersionInfo.FileVersion
    Write-Host "Setup version: $FileVersion"
    dism /Get-WimInfo /WimFile:"${DriveLetter}:\\sources\\install.wim"
}

What is the step-by-step process for executing a Windows Server in-place upgrade?

The in-place upgrade process requires careful execution and monitoring. Unlike clean installations, in-place upgrades preserve your existing configuration, applications, and data while updating the underlying operating system.

Launch the upgrade process from the mounted ISO with administrative privileges:

Start-Process -FilePath "${DriveLetter}:\\setup.exe" -Verb RunAs

During the setup wizard, make these critical selections:

  1. Product Key: Enter your Windows Server 2025 license key
  2. Edition Selection: Choose the same edition as your current installation (Standard/Datacenter)
  3. Installation Type: Select "Keep personal files, apps, and Windows settings"
  4. Updates: Choose "Download and install updates (recommended)"

Monitor the upgrade progress throughout the process. The system will reboot multiple times, and you can check status after each restart:

Get-ItemProperty "HKLM:SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State" | Select-Object ImageState
# IMAGE_STATE_COMPLETE indicates successful completion

Track upgrade phases using the setup log files:

Get-Content "C:\\Windows\\Panther\\setupact.log" | Select-Object -Last 20
# Monitor for error messages or completion status
Warning: RDP connections will disconnect during the upgrade process. Ensure you have console access (physical, iLO, iDRAC) or plan for extended remote access downtime. The upgrade typically takes 2-4 hours.

For multi-step upgrades (such as 2012 R2 → 2016 → 2025), repeat this process for each hop. Allow the system to fully stabilize between upgrades and verify functionality before proceeding to the next version.

How do I verify and troubleshoot post-upgrade issues?

Post-upgrade verification ensures all services, roles, and applications function correctly in the new environment. This phase identifies issues early and provides opportunity for remediation before users are affected.

Verify the upgrade completed successfully:

$OS = Get-WmiObject -Class Win32_OperatingSystem
Write-Host "New Version: $($OS.Caption)"
Write-Host "Build Number: $($OS.BuildNumber)"
Write-Host "Install Date: $($OS.InstallDate)"
winver # Opens version dialog

Compare installed Windows features before and after upgrade:

$PreUpgradeFeatures = Get-Content C:\\Temp\\installed-features.txt
$PostUpgradeFeatures = Get-WindowsFeature | Where-Object InstallState -eq "Installed" | Select-Object -ExpandProperty Name
$MissingFeatures = Compare-Object $PreUpgradeFeatures $PostUpgradeFeatures | Where-Object SideIndicator -eq "<="
if ($MissingFeatures) {
    Write-Host "Missing features detected:" -ForegroundColor Red
    $MissingFeatures.InputObject
}

Test critical system services and network connectivity:

# Check critical services
$CriticalServices = @("Spooler", "DHCP", "DNS", "W32Time", "EventLog", "Netlogon")
foreach ($Service in $CriticalServices) {
    $Status = Get-Service -Name $Service -ErrorAction SilentlyContinue
    if ($Status) {
        Write-Host "$Service: $($Status.Status)" -ForegroundColor $(if($Status.Status -eq "Running"){"Green"}else{"Red"})
    }
}

# Test domain connectivity
Test-ComputerSecureChannel -Verbose
nltest /dsgetdc:$env:USERDNSDOMAIN

Clean up upgrade files and optimize system performance:

# Remove old Windows installation files
Dism /online /Cleanup-Image /StartComponentCleanup /ResetBase
# Run disk cleanup
Cleanmgr /sagerun:1
# Check disk space recovery
Get-WmiObject -Class Win32_LogicalDisk -Filter "DriveType=3" | Select-Object @{Name="Drive";Expression={$_.DeviceID}}, @{Name="FreeSpace(GB)";Expression={[math]::Round($_.FreeSpace/1GB,2)}}

Install latest updates and drivers for the new operating system:

Get-WUInstall -AcceptAll -Install
# Check for hardware issues
Get-WmiObject Win32_PnPEntity | Where-Object{$_.ConfigManagerErrorCode -ne 0} | Select-Object Name, DeviceID
Pro tip: Maintain your system backup for at least 30 days post-upgrade. This provides sufficient time to identify any delayed compatibility issues that might require rollback.

Document the successful upgrade for future reference and compliance:

$UpgradeLog = @{
    "UpgradeDate" = Get-Date
    "SourceVersion" = "Document from pre-upgrade capture"
    "TargetVersion" = (Get-WmiObject Win32_OperatingSystem).Caption
    "UpgradeMethod" = "In-place upgrade"
    "DowntimeHours" = "Document actual downtime"
    "IssuesEncountered" = "List any problems resolved"
}
$UpgradeLog | ConvertTo-Json | Out-File -FilePath C:\\Temp\\upgrade-log.json

This systematic approach to Windows Server upgrades minimizes risk while ensuring successful migration to newer operating system versions. Following these procedures and verification steps provides confidence in your upgraded environment and maintains business continuity throughout the process.

Step-by-Step Implementation

1

Document Current System Configuration

Before starting any upgrade, document your current system thoroughly. This creates a baseline and helps troubleshoot issues later.

Open PowerShell as Administrator and run these commands to capture system information:

Get-ComputerInfo -Property WindowsBuildLabEx,WindowsEditionID,TotalPhysicalMemory | Out-File -FilePath C:\Temp\computerinfo.txt
systeminfo.exe | Out-File -FilePath C:\Temp\systeminfo.txt
ipconfig /all | Out-File -FilePath C:\Temp\ipconfig.txt
Get-WindowsFeature | Where-Object InstallState -eq "Installed" | Out-File -FilePath C:\Temp\installed-features.txt

Document your current Windows Server version and edition:

$OS = Get-WmiObject -Class Win32_OperatingSystem
Write-Host "Current Version: $($OS.Caption)"
Write-Host "Build Number: $($OS.BuildNumber)"
Write-Host "Edition: $($OS.OperatingSystemSKU)"

Copy these files to a USB drive or network location. This documentation will be crucial if you need to restore services or troubleshoot post-upgrade.

2

Verify Supported Upgrade Path

Not all Windows Server versions can upgrade directly to newer versions. Check the official upgrade matrix to determine your path.

Use this PowerShell command to identify your current version:

$Version = (Get-ItemProperty "HKLM:SOFTWARE\Microsoft\Windows NT\CurrentVersion").ReleaseId
$Build = (Get-ItemProperty "HKLM:SOFTWARE\Microsoft\Windows NT\CurrentVersion").CurrentBuild
Write-Host "Release ID: $Version, Build: $Build"

Based on Microsoft's 2026 supported upgrade paths:

Source VersionTo 2016To 2019To 2022To 2025
2008/2008 R2NoNoNoNo
2012YesNoNoNo
2012 R2YesYesNoYes
2016N/AYesYesYes
2019N/AN/AYesYes
2022N/AN/AN/AYes
Warning: Windows Server 2008 and 2008 R2 cannot be upgraded in-place to any modern version. These require migration to new hardware.
3

Prepare System and Create Backups

System preparation is critical for upgrade success. Start by installing all available updates and creating comprehensive backups.

Install Windows Updates:

Install-Module PSWindowsUpdate -Force
Get-WUInstall -AcceptAll -AutoReboot

Create a system backup using Windows Server Backup:

Import-Module WindowsServerBackup
$Policy = New-WBPolicy
$VolumeBackupLocation = New-WBBackupTarget -VolumePath "E:"
Add-WBBackupTarget -Policy $Policy -Target $VolumeBackupLocation
$Volume = Get-WBVolume -VolumePath "C:"
Add-WBVolume -Policy $Policy -Volume $Volume
Start-WBBackup -Policy $Policy

Verify system requirements for the target version. For Windows Server 2025:

$RAM = [math]::Round((Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum).sum /1gb,2)
$Disk = Get-WmiObject -Class Win32_LogicalDisk -Filter "DriveType=3" | Select-Object Size,FreeSpace
Write-Host "RAM: $RAM GB (Minimum: 2GB for Desktop Experience)"
foreach($Drive in $Disk) {
    $FreeGB = [math]::Round($Drive.FreeSpace /1GB,2)
    Write-Host "Free Space: $FreeGB GB (Minimum: 32GB required)"
}
Pro tip: Always create a VM snapshot if running on virtualized infrastructure. This provides the fastest rollback option if the upgrade fails.
4

Download and Prepare Installation Media

Download the Windows Server 2025 ISO from the Microsoft Volume Licensing Service Center or Evaluation Center. You'll need valid credentials and licensing.

Mount the ISO file and verify its contents:

$ISOPath = "C:\Downloads\WindowsServer2025.iso"
$MountResult = Mount-DiskImage -ImagePath $ISOPath -PassThru
$DriveLetter = ($MountResult | Get-Volume).DriveLetter
Write-Host "ISO mounted to drive: $DriveLetter"
Get-ChildItem "${DriveLetter}:\" | Select-Object Name,Length

Verify the setup.exe file exists and check the Windows Server edition available:

$SetupPath = "${DriveLetter}:\setup.exe"
if (Test-Path $SetupPath) {
    Write-Host "Setup.exe found at: $SetupPath"
    $FileVersion = (Get-ItemProperty $SetupPath).VersionInfo.FileVersion
    Write-Host "Setup version: $FileVersion"
} else {
    Write-Host "ERROR: Setup.exe not found!"
}

Check available editions in the ISO:

dism /Get-WimInfo /WimFile:"${DriveLetter}:\sources\install.wim"

Ensure the target edition matches your current installation (Standard to Standard, Datacenter to Datacenter). Mismatched editions will cause upgrade failures.

5

Execute the In-Place Upgrade

Now execute the actual upgrade process. This step requires careful monitoring and can take several hours depending on your system.

Navigate to the mounted ISO and launch setup with elevated privileges:

Start-Process -FilePath "${DriveLetter}:\setup.exe" -Verb RunAs

During the setup wizard:

  1. Enter your product key when prompted
  2. Select the same edition as your current installation
  3. Choose "Keep personal files, apps, and Windows settings" for in-place upgrade
  4. Select "Download and install updates (recommended)" for latest patches

Monitor the upgrade progress. The system will reboot multiple times. You can check progress after each reboot:

Get-ItemProperty "HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\State" | Select-Object ImageState

If the ImageState shows "IMAGE_STATE_COMPLETE", the upgrade finished successfully.

Warning: RDP connections will disconnect during the upgrade process. Use console access or plan for extended downtime. The upgrade can take 2-4 hours depending on system specifications.

Verification after upgrade completion:

$OS = Get-WmiObject -Class Win32_OperatingSystem
Write-Host "New Version: $($OS.Caption)"
Write-Host "Build Number: $($OS.BuildNumber)"
winver
6

Post-Upgrade Verification and Cleanup

After the upgrade completes, verify all services and roles are functioning correctly. This step is crucial to ensure business continuity.

Check all installed Windows features are still present:

Compare-Object (Get-Content C:\Temp\installed-features.txt) (Get-WindowsFeature | Where-Object InstallState -eq "Installed" | Select-Object -ExpandProperty Name)

Verify critical services are running:

$CriticalServices = @("Spooler", "DHCP", "DNS", "W32Time", "EventLog")
foreach ($Service in $CriticalServices) {
    $Status = Get-Service -Name $Service -ErrorAction SilentlyContinue
    if ($Status) {
        Write-Host "$Service`: $($Status.Status)"
    }
}

Test network connectivity and domain membership:

Test-ComputerSecureChannel -Verbose
nltest /dsgetdc:$env:USERDNSDOMAIN

Clean up upgrade files to free disk space:

Dism /online /Cleanup-Image /StartComponentCleanup /ResetBase
Cleanmgr /sagerun:1

Update Windows and install latest drivers:

Get-WUInstall -AcceptAll -Install
Get-WmiObject Win32_PnPEntity | Where-Object{$_.ConfigManagerErrorCode -ne 0} | Select-Object Name, DeviceID
Pro tip: Keep the system backup for at least 30 days after upgrade. This gives you time to identify any delayed issues that might require rollback.

Document the successful upgrade:

$UpgradeLog = @{
    "UpgradeDate" = Get-Date
    "SourceVersion" = "Previous version from documentation"
    "TargetVersion" = (Get-WmiObject Win32_OperatingSystem).Caption
    "UpgradeMethod" = "In-place upgrade"
}
$UpgradeLog | ConvertTo-Json | Out-File -FilePath C:\Temp\upgrade-log.json

Discussion

Share your thoughts and insights

You must be logged in to comment.

Loading comments...