collector/collector.psm1
using module ../utils/utils.psd1 <# .SYNOPSIS Retrieves all resources with matching tags. .DESCRIPTION The Get-WAFTaggedResources function queries Azure Resource Graph to retrieve all resources that have matching tags. .PARAMETER tagArray An array of tags to filter resources by. Each tag should be in the format 'key==value'. .PARAMETER SubscriptionIds An array of subscription IDs to scope the query. .OUTPUTS Returns an array of resources with matching tags. .EXAMPLE $taggedResources = Get-WAFTaggedResources -tagArray @('env==prod', 'app==myapp') -SubscriptionIds @('sub1', 'sub2') .NOTES This function uses the Invoke-WAFQuery function to perform the query. #> function Get-WAFTaggedResource { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string[]] $TagArray, [Parameter(Mandatory = $true)] [AllowEmptyCollection()] [string[]] $SubscriptionIds ) $return = @() foreach ($tag in $TagArray) { switch -Wildcard ($tag) { "*=~*" { $tagKeys = $tag.Split("=~")[0].split("||") -join ("','") $tagValues = $tag.Split("=~")[1].split("||") -join ("','") $in = "in~" } "*!~*" { $tagKeys = $tag.Split("!~")[0].split("||") -join ("','") $tagValues = $tag.Split("!~")[1].split("||") -join ("','") $in = "!in~" } } $tagquery = "resources | mv-expand bagexpansion=array tags | where isnotempty(tags) | where tolower(tags[0]) in~ ('$tagkeys') // Specify your tag names here | where tolower(tags[1]) $in ('$tagvalues') // Specify your tag values here | summarize by id | order by ['id']" $result = Invoke-WAFQuery -Query $tagquery -SubscriptionIds $SubscriptionIds $return += $result } $return = ($return | Group-Object id | Where-Object { $_.count -eq $TagArray.Count } | Select-Object Name).Name return $return } <# .SYNOPSIS Retrieves all resources in resource groups with matching tags. .DESCRIPTION The Get-WAFTaggedRGResources function queries Azure Resource Graph to retrieve all resources in resource groups that have matching tags. .PARAMETER tagKeys An array of tag keys to filter resource groups by. .PARAMETER tagValues An array of tag values to filter resource groups by. .PARAMETER SubscriptionIds An array of subscription IDs to scope the query. .OUTPUTS Returns an array of resources in resource groups with matching tags. .EXAMPLE $taggedRGResources = Get-WAFTaggedRGResources -tagKeys @('env') -tagValues @('prod') -SubscriptionIds @('sub1', 'sub2') .NOTES This function uses the Invoke-WAFQuery function to perform the query. #> function Get-WAFTaggedResourceGroup { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string[]] $TagArray, [Parameter(Mandatory = $true)] [AllowEmptyCollection()] [string[]] $SubscriptionIds ) $return = @() foreach ($tag in $TagArray) { switch -Wildcard ($tag) { "*=~*" { $tagKeys = $tag.Split("=~")[0].split("||") -join ("','") $tagValues = $tag.Split("=~")[1].split("||") -join ("','") $in = "in~" } "*!~*" { $tagKeys = $tag.Split("!~")[0].split("||") -join ("','") $tagValues = $tag.Split("!~")[1].split("||") -join ("','") $in = "!in~" } } $tagquery = ` "resourcecontainers | where type == 'microsoft.resources/subscriptions/resourcegroups' | mv-expand bagexpansion=array tags | where isnotempty(tags) | where tolower(tags[0]) in~ ('$tagKeys') // Specify your tag names here | where tolower(tags[1]) $in ('$tagValues') // Specify your tag values here | summarize by id | order by ['id']" $result = Invoke-WAFQuery -Query $tagquery -SubscriptionIds $SubscriptionIds $return += $result } $return = ($return | Group-Object id | Where-Object { $_.count -eq $TagArray.Count } | Select-Object Name).Name return $return } <# .SYNOPSIS Invokes a loop to run queries for each recommendation object. .DESCRIPTION The Invoke-WAFQueryLoop function runs queries for each recommendation object and retrieves the resources. .PARAMETER RecommendationObject An array of recommendation objects to query. .PARAMETER subscriptionIds An array of subscription IDs to scope the query. .OUTPUTS Returns an array of resources for each recommendation object. .EXAMPLE $resources = Invoke-WAFQueryLoop -RecommendationObject $recommendations -subscriptionIds @('sub1', 'sub2') .NOTES This function uses the Invoke-WAFQuery function to perform the queries. #> function Invoke-WAFQueryLoop { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [PSCustomObject[]] $RecommendationObject, [Parameter(Mandatory = $true)] [AllowEmptyCollection()] [string[]] $SubscriptionIds, [Parameter(Mandatory = $false)] [AllowEmptyCollection()] [string[]] $AddedTypes, [Parameter(Mandatory = $false)] [int] $ProgressId = 1 ) $Types = Get-WAFResourceType -SubscriptionIds $SubscriptionIds $Types += $AddedTypes $QueryObject = Get-WAFQueryByResourceType -ObjectList $RecommendationObject -FilterList $Types.type -KeyColumn 'recommendationResourceType' $return = $QueryObject.Where({ $_.automationAvailable -eq $true -and $_.recommendationMetadataState -eq "Active" -and [string]::IsNullOrEmpty($_.recommendationTypeId) }) | ForEach-Object { Write-Progress -Activity 'Running Queries' -Status "Running Query for $($_.recommendationResourceType) - $($_.aprlGuid)" -PercentComplete (($QueryObject.IndexOf($_) / $QueryObject.Count) * 100) -Id $ProgressId try { (Invoke-WAFQuery -Query $_.query -SubscriptionIds $subscriptionIds -ErrorAction Stop) } catch { Write-Host "Error running query for - $($_.recommendationResourceType) - $($_.aprlGuid)" } } Write-Progress -Activity 'Running Queries' -Status 'Completed' -Completed -Id $ProgressId return $return } <# .SYNOPSIS Retrieves all resource types in the specified subscriptions. .DESCRIPTION The Get-WAFResourceType function queries Azure Resource Graph to retrieve all resource types in the specified subscriptions. .PARAMETER SubscriptionIds An array of subscription IDs to scope the query. .OUTPUTS Returns an array of resource types. .EXAMPLE $resourceTypes = Get-WAFResourceType -SubscriptionIds @('sub1', 'sub2') .NOTES This function uses the Invoke-WAFQuery function to perform the query. #> function Get-WAFResourceType { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [AllowEmptyCollection()] [string[]] $SubscriptionIds ) $q = "Resources | summarize count() by type | project type" $r = $SubscriptionIds ? (Invoke-WAFQuery -Query $q -SubscriptionIds $SubscriptionIds) : (Invoke-WAFQuery -Query $q) return $r } <# .SYNOPSIS Filters objects by resource type. .DESCRIPTION The Get-WAFQueryByResourceType function filters a list of objects by resource type. .PARAMETER ObjectList An array of objects to filter. .PARAMETER FilterList An array of resource types to filter by. .PARAMETER KeyColumn The key column to use for filtering. .OUTPUTS Returns an array of objects that match the specified resource types. .EXAMPLE $filteredObjects = Get-WAFQueryByResourceType -ObjectList $objects -FilterList $types -KeyColumn "type" #> function Get-WAFQueryByResourceType { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [PSCustomObject[]] $ObjectList, [Parameter(Mandatory = $true)] [string[]] $FilterList, [Parameter(Mandatory = $true)] [string] $KeyColumn ) $matchingObjects = foreach ($obj in $ObjectList) { if ($obj.$KeyColumn -in $FilterList) { $obj } } return $matchingObjects } |