Azure Has Put Your Old VMs on the Clock: How to Find Out If You’re Affected

Updated 1 October 2026: the growth restrictions are now in force, and the series list and retirement dates below follow Microsoft Learn’s current retirement and capacity restrictions page.

In July 2026 Azure emailed subscription owners about older VM series. The email waves a comfortable 2028 retirement date at you, so most people archived it and moved on.

The part that actually bites is already live. Since 31 July 2026, a large chunk of the estate people are quietly running can no longer scale or expand. And if you know where to look, there are other deadlines in the background, one of which has already passed.

Here’s what actually changed, how to find out in minutes whether you’re exposed, and the exact commands to plan your way out.

What Microsoft actually announced

The email is titled “Capacity growth restrictions for older generation v1 to v4 Azure VM series.” The wording matters, because two different things are happening at once.

Growth restrictions (in force since 31 July 2026): For the affected series, Azure no longer approves additional quota or capacity expansion, and new subscriptions can’t deploy them at all. Existing subscriptions can still deploy and redeploy within quota they already hold, subject to regional capacity, and existing VMs keep running. You just cannot grow.

Retirement (2028 and 2029): The same families are scheduled for full retirement later. That is the date the email leads with, and it is the one that makes the whole thing feel like a problem for future-you. Per Microsoft Learn, D, Ds, Dv2, Dsv2 and Ls retire on 1 May 2028; F, Fs, Fsv2, Lsv2, G, Gs, Av2, Amv2 and B-series (v1) on 15 November 2028; and Dv3, Dsv3, Ev3 and Esv3 on 15 November 2029.

The series under growth restrictions, as Microsoft Learn lists them today:

  • Compute optimised: F, Fs, Fsv2
  • General purpose: D, Ds, Dv2, Dsv2, Dv3, Dsv3, B, Bs, Av2, Amv2
  • Memory optimised: Ev3, Esv3, G, Gs
  • Storage optimised: Ls, Lsv2

The email’s subject line said "v1 to v4", but the v4 families (Dv4, Dsv4, Ev4 and their variants) are not on Microsoft’s published list, so check the Learn page rather than the subject line before you plan around them.

Read that list again. Dsv3 and Esv3 are on it. Those have been the sensible, widely available default for years, especially if you deploy infrastructure as code and never explicitly overrode the SKU. A lot of production estates are sitting on exactly these sizes right now, often without a clear picture of how those subscriptions and resource groups are even carved up.

Step 1: Find out if you’re affected

Do not trust your memory of what you deployed. Query it.

The fastest way to see every VM size across every subscription you can reach is Azure Resource Graph. Install the extension once:

az extension add --name resource-graph

Then list every VM and its size, sorted so the old generations group together:

az graph query -q "Resources
| where type =~ 'microsoft.compute/virtualmachines'
| extend vmSize = tostring(properties.hardwareProfile.vmSize)
| project name, vmSize, location, resourceGroup, subscriptionId
| order by vmSize asc" --first 1000 -o table

To narrow it down to the likely-restricted families, use the query below. The cleanest place to run it is Azure Resource Graph Explorer in the portal, which sidesteps all the shell-quoting pain (paste the KQL from the first pipe onwards). The logic is: match the affected family letters at v2/v3 or unversioned (v1), and explicitly exclude anything on v4 or later. Treat it as a first pass and cross-check the results against the affected-series list above, because a handful of newer sizes (for example Bsv2) share family letters:

Resources
| where type =~ 'microsoft.compute/virtualmachines'
| extend vmSize = tostring(properties.hardwareProfile.vmSize)
| where vmSize matches regex @'(?i)_(D|DS|E|ES|F|FS|G|GS|A|B|L|LS)[0-9].*'
    and not(vmSize matches regex @'(?i)_v[4-7]$')
| summarize count() by vmSize, location
| order by count_ desc

If that returns rows, you have workloads on the clock. (Some rows, such as Ls_v3 sizes, share family letters but are not on the list; check each against the series list above.) The count() by vmSize, location view tells you how big the job is and which regions it lands in, which matters for the next part.

PowerShell equivalent, if that’s your world:

Search-AzGraph -Query "Resources
| where type =~ 'microsoft.compute/virtualmachines'
| extend vmSize = tostring(properties.hardwareProfile.vmSize)
| project name, vmSize, location, resourceGroup, subscriptionId
| order by vmSize asc" -First 1000

Step 2: Check what you’re actually allowed to deploy

Microsoft’s recommended fix is to move to v5 or newer (Dv5, Dv6, Dv7 for general purpose; Ev5, Ev6, Ev7 for memory). Before you plan around that, confirm those sizes are actually available to you in the region you care about, because “recommended” and “available” are not the same thing.

List the target SKUs in a region and, crucially, their restrictions:

az vm list-skus \
  --location uksouth \
  --resource-type virtualMachines \
  --size Standard_D \
  --all \
  --query "[?contains(name, 'v5') || contains(name, 'v6')].{Name:name, Zones:locationInfo[0].zones, Restrictions:restrictions[].reasonCode}" \
  -o table

A NotAvailableForSubscription restriction against a zone means Azure will not let you deploy that size there right now. If your target size comes back restricted in your target region, that is your capacity crunch made visible, before it bites you in a failed deployment at 2am.

To see which of your subscription’s quotas have headroom for the new families:

az vm list-usage --location uksouth -o table | grep -Ei "DSv5|Dv5|Ev5|Dv6"

Step 3: Get a real migration recommendation

You do not have to guess the right target size. Two options.

Azure Migrate (for estates): Azure Migrate’s assessment engine will right-size your current VMs and recommend a supported target SKU, with a cost estimate. If you’re moving more than a handful of machines, run an assessment rather than eyeballing it. It also flags workloads that are oversized, which is where the migration can quietly pay for itself. And if you’re re-platforming rather than just resizing in place, it’s worth revisiting which landing zone those workloads actually belong in while you have the bonnet up.

Manual mapping (for a few machines): The like-for-like jump is usually the same number, same suffix, next generation. A Standard_D4s_v3 maps to Standard_D4s_v5. Confirm the target exists and is unrestricted with the list-skus command above, then resize:

az vm resize \
  --resource-group my-rg \
  --name my-vm \
  --size Standard_D4s_v5

Resizing deallocates and reallocates the VM, so it reboots. If the new size lives on different underlying hardware (it will, that’s the point), the VM stops and restarts. Schedule it. And here’s the catch that trips people up in a constrained region: if the target size has no capacity in that region when you resize, the VM may not start again. Which is the whole reason to check availability first.

Step 4: The deadline the email doesn’t mention

Now the part that turns this from housekeeping into a real problem.

The capacity email says nothing about what’s running inside those VMs. But if you deployed on v2 or v3 boxes several years ago, there’s a good chance the operating system and database went end-of-life on roughly the same timeline as the hardware.

SQL Server 2016 reached the end of extended support on 14 July 2026. It has already passed. Instances still on it get no security updates unless you’re paying for Extended Security Updates.

Windows Server 2016 follows on 12 January 2027.

So your most business-critical databases can end up in the worst possible position: unsupported operating system, unsupported database engine, sitting on a restricted VM SKU, and needing to move to a region that may not have room for them.

Find the SQL Server versions across your estate. On any individual instance:

SELECT
  SERVERPROPERTY('ProductVersion')      AS Version,
  SERVERPROPERTY('ProductMajorVersion') AS MajorVersion,  -- 13 = SQL Server 2016
  SERVERPROPERTY('ProductLevel')        AS PatchLevel,
  SERVERPROPERTY('Edition')             AS Edition;

Major version 13 is SQL Server 2016. For fleet-wide discovery, Azure Arc-enabled SQL Server inventories every instance and surfaces the version in Azure, which beats logging into boxes one at a time.

Find the Windows Server version on a box:

Get-CimInstance Win32_OperatingSystem | Select-Object Caption, Version, BuildNumber

Across Azure VMs, the original image SKU gives you a fast (if imperfect) first pass:

az graph query -q "Resources
| where type =~ 'microsoft.compute/virtualmachines'
| extend imageSku = tostring(properties.storageProfile.imageReference.sku)
| where imageSku contains '2016'
| project name, imageSku, resourceGroup, location" -o table

Note the caveat: imageReference reflects the image the VM was created from, so it can be blank for specialised or in-place-upgraded machines. Azure Update Manager or Arc gives you the authoritative current build.

Step 5: Watch the cost angle

One more thing that catches people out. If those workloads are covered by a Reserved Instance (a one or three year billing commitment you bought for the discount) and you now plan to change SKU or region, the reservation does not follow the VM automatically, so there can be a cost impact. Per Microsoft Learn, new or renewed reservations are no longer available for the affected v1 to v3 series, and reservation exchanges are available until 1 February 2027 (after that, each eligible reservation keeps one final exchange). Reserved Instance and Capacity Reservation are two different products that unfortunately share the word “reserved”: one is a billing discount, the other is a capacity guarantee. Know which you hold before you move anything.

List your reservation orders so you know what’s committed:

az reservations reservation-order list -o table

If you’re moving into a genuinely constrained region and the workload cannot tolerate a failed allocation, an on-demand Capacity Reservation for the target size reserves the compute for you ahead of time (you pay for it whether or not a VM occupies it):

# Create the reservation group (zonal)
az capacity reservation group create \
  -n my-crg -g my-rg -l uksouth --zones 1 2 3

# Reserve capacity for a specific size in that group
az capacity reservation create \
  -c my-crg -n my-cr -g my-rg -l uksouth \
  --sku Standard_D4s_v5 --capacity 10 --zone 1

The realistic capacity picture

Why does any of this matter if the “fix” is just newer hardware? Because the newer hardware isn’t evenly available.

Microsoft’s own guidance is blunt about it: quota is an approved limit, not a capacity guarantee, and a deployment can still hit an allocation failure if the region or zone is short of capacity. For a UK business with data residency requirements, "just deploy to another region" is not a free move.

If leaning this hard on a single provider’s regions makes you nervous, it should. It’s the same single-point-of-failure lesson three major cloud outages taught us last year. It’s also part of why UK and European sovereign cloud spending is set to triple by 2027: organisations are quietly rethinking how much of their estate sits on infrastructure they do not control.

That is the real message under the polite email: move off the old tin, onto hardware that is already under pressure, before the door closes.

Your migration checklist

If you run anything on Azure, this is a genuine Friday-afternoon job:

  1. Run the Resource Graph query in Step 1. Know which VMs are on the restricted list.
  2. Check your target v5/v6 sizes are unrestricted in your region (Step 2).
  3. Run an Azure Migrate assessment for anything beyond a handful of machines (Step 3).
  4. Inventory Windows Server and SQL Server versions. Flag anything on 2016 (Step 4).
  5. Check your Reserved Instances before you change SKU or region, and use any exchanges before 1 February 2027 (Step 5).
  6. For critical workloads in tight regions, put a Capacity Reservation in now.

None of these deadlines is dramatic on its own. Stacked together (a growth freeze that is already in force, an already-expired database engine, an OS that expires in January 2027, and regions where capacity isn’t guaranteed) they turn a “someday” migration into a this-quarter one.

Lab to Leader

Here’s why this is worth understanding properly rather than just reacting to the email. Anyone can forward a Microsoft notice. The person who gets promoted is the one who can open a terminal, tell their manager exactly how many VMs are affected, which ones carry an end-of-life database, what the target sizes cost, and whether the region has room, all before the panic starts.

That is the difference between reading the manual and running the estate. Capacity planning, lifecycle management, and knowing your cloud provider’s roadmap better than your provider assumes you do: that’s senior cloud architect work, and this email is a free chance to practise it on your own environment.

Go and run the query. You might be pleasantly surprised. Or you might find out you have a very productive few weeks ahead of you.

Enjoyed this guide?

New articles on Linux, homelab, cloud, and automation every 2 days. No spam, unsubscribe anytime.

Scroll to Top