Private/Read-ResourceIdList.ps1
|
function Read-ResourceIdList { <# .SYNOPSIS Reads a list of VM resource IDs from a file -- either a CSV with a 'ResourceId' column (e.g. the export of select-vms-from-cost.kql) or a plain text file with one ID per line. .DESCRIPTION Returns distinct, well-formed VM resource IDs. Lines that aren't a '/subscriptions/.../providers/Microsoft.Compute/virtualMachines/...' path are ignored, so headers, comments (#) and stray text are harmless. .PARAMETER Path Path to the CSV or text file. .OUTPUTS [string[]] distinct VM resource IDs (original casing preserved). #> [CmdletBinding()] [OutputType([string[]])] param( [Parameter(Mandatory)] [string] $Path ) if (-not (Test-Path -Path $Path -PathType Leaf)) { throw "ResourceId file not found: $Path" } $candidates = [System.Collections.Generic.List[string]]::new() # Prefer a CSV with a ResourceId column. $csv = $null try { $csv = Import-Csv -Path $Path -ErrorAction Stop } catch { $csv = $null } $col = $null if ($csv -and $csv.Count -gt 0) { $col = $csv[0].PSObject.Properties.Name | Where-Object { $_ -ieq 'ResourceId' } | Select-Object -First 1 } if ($col) { foreach ($row in $csv) { $candidates.Add([string]$row.$col) } } else { # Fall back to one ID per line. foreach ($line in (Get-Content -Path $Path)) { $candidates.Add([string]$line) } } $vmIdPattern = '^/subscriptions/[^/]+/resourcegroups/[^/]+/providers/microsoft\.compute/virtualmachines/[^/]+$' $seen = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) $clean = [System.Collections.Generic.List[string]]::new() foreach ($c in $candidates) { if (-not $c) { continue } $id = $c.Trim().Trim('"') if ($id -match $vmIdPattern -and $seen.Add($id)) { $clean.Add($id) } } return $clean.ToArray() } |