Public/Find-CloudResource.ps1
|
function Find-CloudResource { <# .SYNOPSIS Searches for cloud resources by name across providers and resource kinds. .DESCRIPTION Find-CloudResource performs a cross-kind, cross-cloud search for resources by name. Use this when you know a resource name but not whether it's a VM, disk, storage account, network, or function, or when you need to search multiple clouds simultaneously. Wildcards are supported in the -Name parameter. .EXAMPLE Find-CloudResource -Name 'payment-svc-03' Searches all providers and all resource kinds for 'payment-svc-03'. .EXAMPLE Find-CloudResource -Name 'prod-*' -Provider Azure, AWS Searches Azure and AWS for any resource starting with 'prod-'. .EXAMPLE Find-CloudResource -Name 'web-*' -Kind Instance, Network Searches for instances and networks with names starting with 'web-'. .EXAMPLE Find-CloudResource -Name '*test*' -Provider GCP -Kind Storage Searches GCP storage resources for names containing 'test'. #> [CmdletBinding()] [OutputType([pscustomobject])] param( # The resource name to search for. Wildcards are supported. [Parameter(Mandatory, Position = 0)] [SupportsWildcards()] [string]$Name, # Limit search to specific providers. If not specified, searches all connected providers. [ValidateSet('Azure', 'AWS', 'GCP')] [string[]]$Provider, # Limit search to specific resource kinds. If not specified, searches all kinds. [ValidateSet('Instance', 'Disk', 'Storage', 'Network', 'Function')] [string[]]$Kind ) process { # Resolve provider list $providersToSearch = if ($Provider) { $Provider | Where-Object { $script:PSCumulusContext.Providers[$_] } } else { @('Azure', 'AWS', 'GCP') | Where-Object { $script:PSCumulusContext.Providers[$_] } } # Resolve kind list $kindsToSearch = if ($Kind) { $Kind } else { @('Instance', 'Disk', 'Storage', 'Network', 'Function') } $results = [System.Collections.Generic.List[psobject]]::new() $azureRgCacheLoaded = $false try { foreach ($providerName in $providersToSearch) { foreach ($kindName in $kindsToSearch) { $commandName = "Get-Cloud$kindName" $scopeParameterSets = [System.Collections.Generic.List[hashtable]]::new() # Add provider-specific scope parameters from context $ctx = $script:PSCumulusContext.Providers[$providerName] $skipProvider = $false switch ($providerName) { 'Azure' { if (-not $azureRgCacheLoaded) { $azureRgCacheLoaded = $true if (Get-Command Get-AzResourceGroup -ErrorAction SilentlyContinue) { $script:__PSCumulusFcrAzureRgCache = @(Get-AzResourceGroup -ErrorAction SilentlyContinue) } else { $script:__PSCumulusFcrAzureRgCache = @() } } if ($script:__PSCumulusFcrAzureRgCache.Count -gt 0) { foreach ($rg in $script:__PSCumulusFcrAzureRgCache) { if (-not [string]::IsNullOrWhiteSpace($rg.ResourceGroupName)) { $scopeParameterSets.Add(@{ ResourceGroup = $rg.ResourceGroupName }) } } } else { Write-Verbose "Find-CloudResource: no resource groups returned for Azure subscription $($ctx.SubscriptionId); skipping." $skipProvider = $true } break } 'AWS' { if ($ctx.Region) { $scopeParameterSets.Add(@{ Region = $ctx.Region }) } else { Write-Verbose "Find-CloudResource: no region found for AWS context; skipping." $skipProvider = $true } break } 'GCP' { if ($ctx.Project) { $scopeParameterSets.Add(@{ Project = $ctx.Project }) } else { Write-Verbose "Find-CloudResource: no project found for GCP context; skipping." $skipProvider = $true } break } } if ($skipProvider) { continue } foreach ($scopeParams in $scopeParameterSets) { try { $commandParams = @{ Provider = $providerName } foreach ($key in $scopeParams.Keys) { $commandParams[$key] = $scopeParams[$key] } $kindResults = & $commandName @commandParams -ErrorAction SilentlyContinue if ($kindResults) { foreach ($result in $kindResults) { # Add Kind property if not already present if (-not $result.PSObject.Properties.Match('Kind').Count) { $result | Add-Member -MemberType NoteProperty -Name 'Kind' -Value $kindName -Force } # Filter by name if ($result.Name -like $Name) { $results.Add($result) } } } } catch { Write-Verbose "Find-CloudResource: Failed to query $providerName $kindName`: $_" } } } } } finally { Remove-Variable -Scope Script -Name __PSCumulusFcrAzureRgCache -ErrorAction SilentlyContinue } $results } } |