= Copilot Prompt to Get All Unattached Disks in an Azure Subscription =
**Summary**: This wiki page shows how I used copilot to get all unattached disks in an Azure subscription. It's part of the 'copilot' tag series in which I showcase the use of copilot in infrastructure related tasks.\\
**Date**: 2 December 2025 \\
{{tag>copilot azure powershell azurecli}}
I've been using copilot for a while now, and I mostly use it without using a prompt. I let it finish my sentences, or create a small comment and wait for a few seconds to let copilot to give me some hints on how to proceed. But sometimes I also use a prompt, and on this page I show you how I used some prompts to create a script.
The hard facts:
* IDE: VS Code, 1.106.3
* Copilot Extension Version: 1.388.0
* Model: Claude Sonnet 4
= The Prompt =
Actually, I used two prompts. The first prompt was:
> I need an azure cli script that will get all disks from an Azure subscription that have the disk state unattached. In the output I want to see the name, the resourcegroup, the last ownership update time, the location, the time created, the disk size, and the following tags: k8s-azure-created-by, kubernetes.io-created-for-pvc-namespace, kubernetes.io-created-for-pvc-name
This created a script, which with some small modifications worked, except that it didn't return the tags. I found that using the azure cli query option didn't retrieve the tags, so I added another prompt:
> The output doesn't display the tags. I think the az disk list can't resolve the tag information. I think you need to retrieve the tags separately for each disk
This created a new script, which again needed some small modifications.
= The Final Script =
Note that this is the script after my modifications. For the modifications, see below. Copilot also provided the possible ways to start the script:
# Display the output for a subscription
.\get-unattached-disks.ps1 -SubscriptionId "your-subscription-id"
# Export to CSV
.\get-unattached-disks.ps1 -SubscriptionId "your-subscription-id" -OutputToCSV -OutputPath "my-disks.csv"
# Get all unattached disks from Azure subscription with detailed information
# This script retrieves disks with state "Unattached" and displays relevant metadata
param(
[string]$SubscriptionId = $null,
[switch]$OutputToCSV = $false,
[string]$OutputPath = "unattached-disks.csv"
)
# Set subscription if provided
if ($SubscriptionId) {
Write-Host "Setting subscription to: $SubscriptionId" -ForegroundColor Yellow
az account set --subscription $SubscriptionId
}
# Get current subscription info
$currentSub = az account show --query "{name:name, id:id}" -o json | ConvertFrom-Json
Write-Host "Current subscription: $($currentSub.name) ($($currentSub.id))" -ForegroundColor Green
# First get basic disk information for unattached disks
$basicQuery = @"
[?diskState=='Unattached'].{Name: name, ResourceGroup: resourceGroup, LastOwnershipUpdateTime: LastOwnershipUpdateTime, Location: location, TimeCreated: timeCreated, DiskSizeGB: diskSizeGB}
"@
Write-Host "Retrieving basic disk information..." -ForegroundColor Yellow
$basicDisks = az disk list --query $basicQuery -o json | ConvertFrom-Json
if ($basicDisks.Count -eq 0) {
Write-Host "No unattached disks found in the subscription." -ForegroundColor Green
exit 0
}
Write-Host "Found $($basicDisks.Count) unattached disk(s). Retrieving tag information..." -ForegroundColor Yellow
# Now retrieve tags for each disk individually
$disks = @()
$counter = 0
foreach ($disk in $basicDisks) {
$counter++
Write-Progress -Activity "Retrieving disk tags" -Status "Processing disk $counter of $($basicDisks.Count): $($disk.Name)" -PercentComplete (($counter / $basicDisks.Count) * 100)
# Get tags for this specific disk
$tags = az disk show --name $disk.Name --resource-group $disk.ResourceGroup --query "tags" -o json | ConvertFrom-Json
# Create enriched disk object
$enrichedDisk = [PSCustomObject]@{
Name = $disk.Name
ResourceGroup = $disk.ResourceGroup
LastOwnershipUpdateTime = $disk.LastOwnershipUpdateTime
Location = $disk.Location
TimeCreated = $disk.TimeCreated
DiskSizeGB = $disk.DiskSizeGB
CreatedBy = $tags.'k8s-azure-created-by'
PVCNamespace = $tags.'kubernetes.io-created-for-pvc-namespace'
PVCName = $tags.'kubernetes.io-created-for-pvc-name'
#AllTags = $tags
}
$disks += $enrichedDisk
}
Write-Progress -Activity "Retrieving disk tags" -Completed
Write-Host "Completed retrieving tag information for all disks." -ForegroundColor Green
Write-Host ""
if ($OutputToCSV) {
# Output to CSV
$disks | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8
Write-Host "Results exported to: $OutputPath" -ForegroundColor Green
} else {
# Display in table format
$disks | Format-Table -AutoSize -Property @(
'Name',
'ResourceGroup',
@{Name='LastOwnershipUpdate'; Expression={$_.LastOwnershipUpdateTime}; Width=20},
'Location',
@{Name='TimeCreated'; Expression={$_.TimeCreated}; Width=20},
@{Name='SizeGB'; Expression={$_.DiskSizeGB}; Width=8},
@{Name='CreatedBy'; Expression={$_.CreatedBy}; Width=20},
@{Name='PVCNamespace'; Expression={$_.PVCNamespace}; Width=15},
@{Name='PVCName'; Expression={$_.PVCName}; Width=15}
)
}
# Summary
Write-Host ""
Write-Host "=== SUMMARY ===" -ForegroundColor Cyan
Write-Host "Total unattached disks: $($disks.Count)" -ForegroundColor White
$totalSizeGB = ($disks | Measure-Object -Property DiskSizeGB -Sum).Sum
Write-Host "Total size: $totalSizeGB GB" -ForegroundColor White
# Group by resource group
$byResourceGroup = $disks | Group-Object -Property ResourceGroup | Sort-Object Count -Descending
Write-Host ""
Write-Host "By Resource Group:" -ForegroundColor Cyan
foreach ($group in $byResourceGroup) {
$groupSizeGB = ($group.Group | Measure-Object -Property DiskSizeGB -Sum).Sum
Write-Host " $($group.Name): $($group.Count) disks ($groupSizeGB GB)" -ForegroundColor White
}
# Show Kubernetes-related disks
$k8sDisks = $disks | Where-Object { $_.CreatedBy -or $_.PVCNamespace -or $_.PVCName }
if ($k8sDisks.Count -gt 0) {
Write-Host ""
Write-Host "Kubernetes-related disks: $($k8sDisks.Count)" -ForegroundColor Magenta
# Show detailed Kubernetes disk information
Write-Host ""
Write-Host "Kubernetes Disk Details:" -ForegroundColor Magenta
$k8sDisks | Format-Table -AutoSize -Property @(
'Name',
@{Name='CreatedBy'; Expression={$_.CreatedBy}; Width=20},
@{Name='PVCNamespace'; Expression={$_.PVCNamespace}; Width=15},
@{Name='PVCName'; Expression={$_.PVCName}; Width=20},
@{Name='SizeGB'; Expression={$_.DiskSizeGB}; Width=8}
)
}
= Modifications Made =
> Tags
In the first version of the script, the query also tried to retrive the tags. This was not allowed by the query syntax, so I had to remove that from the query.
> Basic query
Originally, copilot had a very easy to read query, with every field in a separate line. However, that gave the following error:
ERROR: argument --query: invalid jmespath_type value: "[?diskState=='Unattached'].{"
To learn more about --query, please visit: 'https://learn.microsoft.com/cli/azure/query-azure-cli'
I updated the query to be just on one line, which solved the issue.
> Basic query fields
Two of the fields the query would ask for did not work. I had to check the actual field names in the output of `az disk list`. The fields `LastOwnershipUpdateTime` and `diskSizeGB` had wrong casing. I updated them to the correct casing.
> All Tags
Even though I didin't ask for it, copilot also added the field `AllTags`, which contained all tags as a hashtable. It worked, but it made the csv output messy, so I commented the field out.
//This wiki has been made possible by://