Compartir a través de

使用 Azure CLI 查找和删除未附加的 Azure 托管和非托管磁盘

适用于:✔️ Linux 虚拟机 ✔️ 灵活规模集

删除 Azure 中的虚拟机 (VM) 时,默认不删除附加到 VM 的任何磁盘。 此功能可帮助防止意外删除 VM 而导致的数据丢失。 删除 VM 后,您仍需为未连接的磁盘继续付款。 本文演示了如何查找并删除任何未附加的磁盘,以及如何减少不必要的成本。

注意事项

使用 az disk show 命令获取任何磁盘的 LastOwnershipUpdateTime。 此属性显示上次更新磁盘的状态的时间。 对于未附加的磁盘,此属性显示未附加磁盘的时间。 对于新创建的磁盘,此属性为空,直到磁盘状态发生更改为止。

托管磁盘:查找并删除未附加的磁盘

以下脚本通过检查 ManagedBy 属性的值查找未附加的托管磁盘。 将托管磁盘附加到 VM 时, ManagedBy 属性包含 VM 的资源 ID。 未附加托管磁盘时,ManagedBy 属性为 null。 该脚本检查 Azure 订阅中的所有托管磁盘。 当脚本找到一个 ManagedBy 属性设置为 null 的托管磁盘时,脚本将确定该磁盘处于未附加状态

重要

首先,通过将 deleteUnattachedDisks 变量设置为 0 来运行脚本。 通过此操作可查找并查看所有未附加的托管磁盘。

在检查所有未附加磁盘后,再次运行脚本并将 deleteUnattachedDisks 变量设置为 1。 通过此操作可删除所有未附加的托管磁盘。

# 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

非托管磁盘:查找并删除未附加的磁盘

非托管磁盘是指以页 blob 形式存储在 Azure 存储帐户中的 VHD 文件。 以下脚本通过检查LeaseStatus属性的值来查找未附加的非托管页 blob 磁盘。 将非托管磁盘附加到 VM 时, LeaseStatus 属性为 Locked。 当未附加非托管磁盘时, LeaseStatus 属性将 解锁。 该脚本检查 Azure 订阅中所有 Azure 存储帐户中的所有非托管磁盘。 当脚本找到一个非托管磁盘,并将 LeaseStatus 属性设置为 Unlocked 时,该脚本将确定该磁盘未附加。

重要

首先,通过将 deleteUnattachedVHDs 变量设置为 0 来运行脚本。 这样,便可以查找和查看所有未附加的不受管理的 VHD。

在检查所有未附加磁盘后,再次运行脚本并将 deleteUnattachedVHDs 变量设置为 1。 这会删除所有未附加且非托管的 VHD。

# 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 

后续步骤

有关详细信息,请参阅删除存储帐户