-
-
Save jasond2014/9f8a6f0f8b045e5a2891915adab9c69a to your computer and use it in GitHub Desktop.
Generate a report of all Azure and AWS disks (volumes) that are not attached to a virtual machine. Output to stdout or to CSV file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Requires -Version 6.0 | |
#Requires -Modules Az.Accounts, Az.ResourceGraph | |
<# | |
.SYNOPSIS | |
Generate a report of Azure orphaned volumes | |
.DESCRIPTION | |
Generate a report of Azure Disks which are not attached to any virtual machine | |
.EXAMPLE | |
Process all Azure Subscriptions and write results to stdout | |
.\Get-AzOrphanedVolumes.ps1 | |
.EXAMPLE | |
Process a single Azure Subscription and write results to stdout | |
.\Get-AzOrphanedVolumes.ps1 -Subscription 'mysubscription1' | |
.EXAMPLE | |
Process multiple Azure Subscriptions and write results to CSV file in the current user's profile directory | |
.\Get-AzOrphanedVolumes.ps1 -Subscription 'mysubscription1', 'mysubscription2' -GenerateReport | |
.EXAMPLE | |
Process all Azure Subscriptions and write results to CSV file in user-defined location | |
.\Get-AzOrphanedVolumes.ps1 -GenerateReport -OutFile 'C:\Users\myuser\Desktop\AzOrphanedVols.csv' | |
#> | |
#region Init | |
param( | |
# String array of Azure Subscription names to process | |
[Parameter()] | |
[string[]] $Subscription, | |
# Whether to output the results to a CSV file | |
[Parameter()] | |
[switch] $GenerateReport, | |
# User-defined location for output CSV file | |
[Parameter()] | |
[string] $OutFile | |
) | |
# Report location | |
if ($GenerateReport -and -not $OutFile) { | |
if ($IsWindows) { | |
$ReportFile = "$env:USERPROFILE\AzureOrphanedVolumes_$(Get-Date -Format 'yyyy-MM-dd').csv" | |
} else { | |
$ReportFile = "$env:HOME/AzureOrphanedVolumes_$(Get-Date -Format 'yyyy-MM-dd').csv" | |
} | |
} else { | |
$ReportFile = $OutFile | |
} | |
#endregion Init | |
#region ProcessAzure | |
try { | |
# Login to Azure and select correct Subscription(s) | |
#Connect-AzAccount | |
if (-not $Subscription) { | |
$Subscriptions = Get-AzSubscription | Select-Object -ExpandProperty Id | |
} else { | |
$Subscriptions = $Subscription | ForEach-Object { | |
Get-AzSubscription -SubscriptionName $_ | Select-Object -ExpandProperty Id | |
} | |
} | |
} catch { | |
Write-Error "Error connecting to Azure: $_" -ErrorAction Stop | |
} | |
try { | |
$Query = @' | |
resources | |
| where type =~ 'microsoft.compute/disks' | |
| where (coalesce(split(managedBy, '/')[(-1)], '-')) =~ '-' | |
'@ | |
# Execute Azure Resource Graph query to find orphaned disks in selected Subscriptions | |
$AzOrphanedVols = Search-AzGraph -Subscription $Subscriptions -Query $Query -First 1000 | Select-Object -ExpandProperty Data | |
} catch { | |
Write-Error "Error executing Azure Resource Graph query: $_" | |
} | |
$AzOrphanedVolObjects = foreach ($OrphanedVol in $AzOrphanedVols) { | |
# Construct Azure output objects | |
[PSCustomObject]@{ | |
Subscription = (Get-AzSubscription -SubscriptionId $OrphanedVol.subscriptionId).Name | |
Location = $OrphanedVol.location | |
Id = $OrphanedVol.id | |
Name = $OrphanedVol.name | |
SizeGB = $OrphanedVol.properties.diskSizeGB | |
CreationDate = $OrphanedVol.properties.timeCreated | |
} | |
} | |
#endregion ProcessAzure | |
#region Output | |
if ($GenerateReport) { | |
try { | |
# Export PowerShell object arrays to CSV file | |
$AzOrphanedVolObjects | Export-Csv -Path $ReportFile -NoTypeInformation | |
} catch { | |
Write-Error "Error exporting orphaned volumes object array to CSV file [$ReportFile]: $_" | |
} | |
} else { | |
$AzOrphanedVolObjects | |
} | |
#endregion Output |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment