Hands-on guide · Updated June 2026

How to Find (and Safely Delete) Orphaned Disks in Azure

By the CloudFinOpsKit team — the people who build and maintain 75+ automated Azure cost checks. 9 min read.

Orphaned managed disks are the single most common piece of waste we find in Azure environments — and one of the easiest to fix. When a VM is deleted, its OS and data disks are not deleted by default (unless someone ticked "delete with VM"). The disk stays behind, fully billed, attached to nothing, doing nothing. Multiply that by years of VM churn, AVD pools, dev experiments and migrations, and most tenants are carrying a quiet four-to-five-figure annual bill for storage nobody is using.

What an orphaned disk actually costs

Managed disks bill for provisioned capacity, not usage. Attached or not, running VM or not, the meter runs. Approximate pay-as-you-go list prices (LRS, varies by region):

DiskSize~Monthly list price~Annual if forgotten
Premium SSD P10128 GB~$20~$240
Premium SSD P20512 GB~$81~$970
Premium SSD P301 TB~$135~$1,620
Standard SSD E20512 GB~$25~$300

Ten forgotten P20s is roughly $9,700 a year — for nothing. ZRS redundancy costs ~50% more again.

Method 1 — the Azure Portal (quick spot-check)

  1. Search for Disks in the portal.
  2. Add the column Disk state, then filter it to Unattached.
  3. Sort by size descending — your biggest savings are at the top.

Fine for a one-off look at a single subscription. It does not scale to a tenant, and it tells you nothing about the traps below.

Method 2 — Azure Resource Graph (the right way at scale)

Resource Graph queries every subscription you can read in one shot. In Cloud Shell or anywhere az is installed:

az graph query -q "
Resources
| where type =~ 'microsoft.compute/disks'
| where isempty(managedBy) and properties.diskState == 'Unattached'
| extend sizeGB = toint(properties.diskSizeGB), sku = tostring(sku.name)
| project name, resourceGroup, subscriptionId, location, sizeGB, sku
| order by sizeGB desc"

The two conditions matter: managedBy empty (no VM owns it) and diskState == 'Unattached'. A disk in Reserved state, for example, belongs to a stopped-but-allocated VM.

The traps: disks that look orphaned but aren't

This is where most cleanup scripts go wrong. We learned these the hard way building our own scanner, and they're the difference between savings and an incident:

1. Azure Site Recovery replica disks

ASR keeps replica disks in your DR region that report as Unattached — because no VM is attached yet. They're named ms-asr-* and are actively written to by replication, linked to a Recovery Services vault. Delete one and you've silently broken your disaster recovery. Exclude anything matching ms-asr- or tagged for Site Recovery from any cleanup.

2. Disks on deallocated VMs

A stopped (deallocated) VM stops billing compute, but its disks keep billing in full. These are not orphaned — but they are a separate finding worth its own review: if the VM has been off for months, snapshot and delete the disks, or delete the whole VM.

3. Recently detached disks

A disk detached yesterday might be mid-maintenance. Check properties.timeCreated and your change records before assuming abandonment. A grace period (below) makes this a non-issue.

4. Snapshots are a different cleanup

Snapshots in AzureBackupRG_* resource groups are Azure Backup instant-restore points — service-managed, don't touch. Old manual snapshots whose source disk still exists may be deliberate DR retention. The genuinely safe target is disconnected snapshots whose source disk no longer exists.

The safe deletion workflow

  1. Exclude the trapsms-asr-*, backup RGs, anything tagged DoNotDelete.
  2. Snapshot first. A snapshot of a 512 GB disk costs a fraction of the disk itself:
    az snapshot create -g RG -n disk01-final-snap --source disk01 --incremental true
  3. Tag and announce. az disk update -g RG -n disk01 --set tags.DeleteAfter=2026-07-15 — then tell the owning team.
  4. Wait the grace period (14–30 days is typical), then delete:
    az disk delete -g RG -n disk01 --yes
  5. Retire the snapshot after a further quarter if nobody has needed it.

Or let the scanner do all of this for you. The CloudFinOpsKit Tool ($25, one-click, read-only) finds every unattached disk across your whole tenant, automatically excludes Site Recovery replicas and backup snapshots, prices each finding from your actual billed cost (falling back to live retail rates), and gives you the exact delete commands — alongside 75+ other checks.

Want the manual route first? Grab the free Azure Cost Review Checklist and make orphaned-disk review a monthly habit.

Stop them coming back

FAQ

Do unattached disks really cost full price?

Yes — managed disks bill provisioned capacity regardless of attachment or VM power state. The meter only stops at deletion.

Are ms-asr-* disks safe to delete?

No. They're Azure Site Recovery replicas that only look unattached. Deleting them breaks replication. Exclude them always.

Should I delete or snapshot-then-delete?

Snapshot first, always. It costs little, and it converts an irreversible action into a reversible one during your grace period.

Related reading: the full 47-point Azure cost optimization checklist · Reserved Instances vs Savings Plans · the best Azure cost tools in 2026