Find and delete unattached Azure managed and unmanaged disks using the Azure CLI
Applies to: ✔️ Linux VMs ✔️ Flexible scale sets
When you delete a virtual machine (VM) in Azure, by default, any disks that are attached to the VM aren't deleted. This feature helps to prevent data loss due to the unintentional deletion of VMs. After a VM is deleted, you will continue to pay for unattached disks. This article shows you how to find and delete any unattached disks and reduce unnecessary costs.
Note
You can use the az disk show command to get the LastOwnershipUpdateTime for any disk. This property represents when the disk’s state was last updated. For an unattached disk, this shows the time when the disk was unattached. This property is blank for newly created disks, until their state changes.
Managed disks: Find and delete unattached disks
The following script looks for unattached managed disks by examining the value of the ManagedBy property. When a managed disk is attached to a VM, the ManagedBy property contains the resource ID of the VM. When a managed disk is unattached, the ManagedBy property is null. The script examines all the managed disks in an Azure subscription. When the script locates a managed disk with the ManagedBy property set to null, the script determines that the disk is unattached.
Important
First, run the script by setting the deleteUnattachedDisks variable to 0. This action lets you find and view all the unattached managed disks.
After you review all the unattached disks, run the script again and set the deleteUnattachedDisks variable to 1. This action lets you delete all the unattached managed disks.
# Set deleteUnattachedDisks=1 if you want to delete unattached Managed Disks
# Set deleteUnattachedDisks=0 if you want to see the Id of the unattached Managed Disks
deleteUnattachedDisks=0
unattachedDiskIds=$(az disk list --query '[?managedBy==`null`].[id]' -o tsv)
for id in ${unattachedDiskIds[@]}
do
if (( $deleteUnattachedDisks == 1 ))
then
echo "Deleting unattached Managed Disk with Id: "$id
az disk delete --ids $id --yes
echo "Deleted unattached Managed Disk with Id: "$id
else
echo $id
fi
done
Unmanaged disks: Find and delete unattached disks
Unmanaged disks are VHD files that are stored as page blobs in Azure storage accounts. The following script looks for unattached unmanaged disks (page blobs) by examining the value of the LeaseStatus property. When an unmanaged disk is attached to a VM, the LeaseStatus property is set to Locked. When an unmanaged disk is unattached, the LeaseStatus property is set to Unlocked. The script examines all the unmanaged disks in all the Azure storage accounts in an Azure subscription. When the script locates an unmanaged disk with a LeaseStatus property set to Unlocked, the script determines that the disk is unattached.
Important
First, run the script by setting the deleteUnattachedVHDs variable to 0. This action lets you find and view all the unattached unmanaged VHDs.
After you review all the unattached disks, run the script again and set the deleteUnattachedVHDs variable to 1. This action lets you delete all the unattached unmanaged VHDs.
# Set deleteUnattachedVHDs=1 if you want to delete unattached VHDs
# Set deleteUnattachedVHDs=0 if you want to see the details of the unattached VHDs
deleteUnattachedVHDs=0
storageAccountIds=$(az storage account list --query [].[id] -o tsv)
for id in ${storageAccountIds[@]}
do
connectionString=$(az storage account show-connection-string --ids $id --query connectionString -o tsv)
containers=$(az storage container list --connection-string $connectionString --query [].[name] -o tsv)
for container in ${containers[@]}
do
blobs=$(az storage blob list --show-next-marker -c $container --connection-string $connectionString --query "[?properties.blobType=='PageBlob' && ends_with(name,'.vhd')].[name]" -o tsv)
for blob in ${blobs[@]}
do
leaseStatus=$(az storage blob show -n $blob -c $container --connection-string $connectionString --query "properties.lease.status" -o tsv)
if [ "$leaseStatus" == "unlocked" ]
then
if (( $deleteUnattachedVHDs == 1 ))
then
echo "Deleting VHD: "$blob" in container: "$container" in storage account: "$id
az storage blob delete --delete-snapshots include -n $blob -c $container --connection-string $connectionString
echo "Deleted VHD: "$blob" in container: "$container" in storage account: "$id
else
echo "StorageAccountId: "$id" container: "$container" VHD: "$blob
fi
fi
done
done
done
Next steps
For more information, see Delete a storage account.