= 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://