Simon Vedder

Cloud Engineer · Zürich

PowerShell module · Bicep orchestrator

AzureInPlaceUpgrade

Take an Azure VM from Windows Server 2016, 2019 or 2022 to 2025 without an RDP session. Read-only preflight, an OS disk snapshot and unattended Setup in one workflow.

Install-Module AzureInPlaceUpgrade -AllowPrerelease

licenseMITPowerShell7.2+galleryv0.3.1-previewpreflightread-onlytargetsWS2016/2019/2022 → 2025

pwsh · Az.Compute
# 1. Read-only preflight — a short Run Command probe, nothing changes
Test-InPlaceUpgradeReadiness -ResourceGroupName rg-apps -Name vm-app-01 -Target WS2025
Decision  Eligible   ·  19 checks, 0 blocking
# 2. Name a VM and a target: snapshot, media disk, Setup as SYSTEM
$s = Start-InPlaceUpgrade -ResourceGroupName rg-apps -Name vm-app-01 -Target WS2025
Setup started  ·  returns in minutes, $s carries the resume values
# 3. Every 20 minutes until Completed or Failed — locally or from Automation
Complete-InPlaceUpgrade -ResourceGroupName rg-apps -Name vm-app-01 -Target WS2025 -Snapshot $s.Snapshot
vm-app-01  Completed   ·  Windows Server 2025, build 26100

Quick start

Run it against one VM

From a workstation with PowerShell 7.2 and the Az modules. Nothing is deployed into your subscription and no tags are involved. You name the machine and the target, and the preflight refuses anything it does not like.

Needs the upgrade operator actions on the VM, or Virtual Machine Contributor · Prerequisites

  1. Install the module and sign in

    Install-Module AzureInPlaceUpgrade -AllowPrerelease
    Connect-AzAccount
  2. Check the machine first

    Nineteen read-only checks inside the guest. Nothing is created, attached or started.

    Test-InPlaceUpgradeReadiness -ResourceGroupName rg-apps-prod-weu -Name vm-app-prod-weu-01 -Target WS2025
  3. Upgrade it

    Snapshot, media disk, unattended Setup, and wait for the guest to report the target build. -WhatIf works everywhere, and -ReuseSnapshot makes a rerun cheap.

    Invoke-InPlaceUpgrade -ResourceGroupName rg-apps-prod-weu -Name vm-app-prod-weu-01 -Target WS2025
  4. Or start it and come back later

    An Azure Automation job dies after three hours, so start and check are separate commands. Start returns in minutes and hands you the line that finishes the job.

    $s = Start-InPlaceUpgrade -ResourceGroupName rg-apps-prod-weu -Name vm-app-prod-weu-01 -Target WS2025
    $s.ResumeCommand

Ready for more than one machine? Run it against a fleet

What it does

What it does

Nobody logs on

No RDP session, no ISO mounted by hand, no answer file written on the machine. Setup runs unattended from a media disk.

Nineteen checks before anything

Disk space, pending reboots, build and edition, agent health. The preflight is read-only and refuses rather than repairs.

A snapshot every time

The OS disk is snapshotted before Setup starts, and a rerun can reuse it instead of paying for a second one.

Start and check are separate

Because an Automation job dies after three hours and an upgrade does not. Progress is read from the guest, not assumed.

Tags only in fleet mode

Running one machine takes a name. Rings, parallelism and schedules exist only once you deploy the orchestrator.

Every run recorded

One row per attempt in Log Analytics, with the workbook that shows which ring is where.

Proof

Supported paths

Shipped as targets.json. A tag value that is not a key there never reaches an Azure image. Same edition, same installation type, 64-bit, en-US, Standard and Datacenter, Server and Server Core. Windows Server Azure Edition is out of scope.

TargetSourceMediaDisk engineFeatureUpdate engine
WS2025Windows Server 2022Verified — Desktop Experience and CoreVerified once
WS2025Windows Server 2019Verified — through Azure AutomationDocumented
WS2025Windows Server 2016VerifiedNot available
WS2025Windows Server 2012 R2Documented by MicrosoftNot available
WS2022Windows Server 2016, 2019Documented by MicrosoftNot available
WS2019Windows Server 2012 R2, 2016Documented by MicrosoftNot available

"Verified" means the path ran end to end in this project's lab on a Marketplace VM; runs, timings and result objects are in docs/verification.md. The media disk finishes in 37 to 43 minutes; the feature update took two to three hours on the same image.

In-place upgrades · Azure Monitor workbook · sample data
The In-place upgrades workbook: tiles counting VMs by state, the latest record per VM with source and target build, engine, duration and snapshot, a failures table, and activity over time

FAQ

Questions people ask first

Does it reboot my VM?

The module never does. Windows Setup reboots the VM several times on its own once it runs, which is why Setup is started as a scheduled task and not from Run Command. A reboot that is already pending before the start blocks the preflight — restart first, then start the upgrade.

What is the 0xC1900215 error, and why does the module care?

Under /quiet, Setup cannot ask which image to install, and the upgrade media carries a Core and a Desktop Experience image per edition. Setup logs "Image selection response not found" and gives up with 0xC1900215. A product key does not help. The module lists the images in install.wim, matches EditionId and InstallationType of the guest and passes /installfrom and /imageindex every time.

How long does an upgrade take?

With the media disk, 37 to 43 minutes end to end in the lab, on Marketplace VMs from 2016, 2019 and 2022. The feature update engine took two to three hours on the same 2022 image. Budget a 60 to 120 minute maintenance window per VM, plus reboots.

Can I roll back?

Start creates an incremental snapshot of the OS disk before anything changes and returns its name; in fleet mode the runbook also records it in the UpgradeSnapshot tag. Complete keeps it — it stays until you delete it. Restoring means creating a disk from the snapshot and swapping the OS disk; test that once in a lab before you trust it.

Is an upgraded VM still supported by Microsoft?

Microsoft's Azure documentation says the in-place upgrade causes a disconnection between the VM's data plane and control plane, and that automatic guest patching, automatic OS image upgrades, hotpatching and Azure Update Manager are not officially supported afterwards. The image reference never changes. If you need those features, Microsoft's recommendation is a new VM — and so is mine.

What does a run cost?

An incremental snapshot of the OS disk, and a managed disk for the upgrade media for the duration of the run. Complete deletes the media disk; the snapshot stays until you remove it. There is no agent, no extension and nothing that keeps running afterwards.

Forty servers and a deadline?

I run this against fleets as part of an Azure engagement — preflight report first, rings and maintenance windows agreed, the failures walked through afterwards.

Get in touch