Private/Get-AutomationRules.ps1
|
function Get-AutomationRules { <# .SYNOPSIS Fetches Sentinel automation rules and extracts close-incident targeting hints. .OUTPUTS Array of PSCustomObject automation rules. #> [CmdletBinding()] param( [Parameter(Mandatory)][PSCustomObject]$Context ) $headers = @{ Authorization = "Bearer $($Context.ArmToken)" } $uri = "https://management.azure.com$($Context.ResourceId)" + "/providers/Microsoft.SecurityInsights/automationRules?api-version=2025-09-01" $allRules = [System.Collections.Generic.List[object]]::new() $maxPages = 1000 $pageCount = 0 do { $pageCount++ $response = Invoke-AzRestWithRetry -Uri $uri -Headers $headers foreach ($rule in $response.value) { $allRules.Add($rule) } $uri = $response.nextLink if ($pageCount -ge $maxPages) { Write-Warning 'Pagination limit reached fetching automation rules. Stopping to avoid infinite loop.' break } } while ($uri) $normalized = foreach ($rule in $allRules) { $props = $rule.properties $actions = @($props.actions) $conditions = @($props.triggeringLogic.conditions) # Detect close action: check for Closed or Resolved status $closeAction = $actions | Where-Object { $_.actionType -eq 'ModifyProperties' -and $_.order -ge 0 -and $_.actionConfiguration -and ($_.actionConfiguration.status -eq 'Closed' -or $_.actionConfiguration.status -eq 'Resolved') } $titleFilters = [System.Collections.Generic.List[string]]::new() $titleOperators = [System.Collections.Generic.List[string]]::new() $ruleIdFilters = [System.Collections.Generic.List[string]]::new() $hasConditions = $conditions.Count -gt 0 # Recursively extract Property conditions (handles Boolean wrappers) $propertyConditions = [System.Collections.Generic.List[object]]::new() $condStack = [System.Collections.Generic.Stack[object]]::new() foreach ($c in $conditions) { $condStack.Push($c) } while ($condStack.Count -gt 0) { $cond = $condStack.Pop() $condType = "$($cond.conditionType)" if ($condType -eq 'Property') { [void]$propertyConditions.Add($cond) } elseif ($condType -eq 'Boolean' -and $cond.conditionProperties.innerConditions) { foreach ($inner in $cond.conditionProperties.innerConditions) { $condStack.Push($inner) } } } foreach ($cond in $propertyConditions) { $propertyName = "$($cond.conditionProperties.propertyName)" $operator = "$($cond.conditionProperties.operator)" # Title conditions if ($propertyName -match 'Title') { $value = $cond.conditionProperties.propertyValues if ($value -is [System.Array]) { foreach ($item in $value) { if (-not [string]::IsNullOrWhiteSpace("$item")) { [void]$titleFilters.Add("$item") [void]$titleOperators.Add($operator) } } } elseif (-not [string]::IsNullOrWhiteSpace("$value")) { [void]$titleFilters.Add("$value") [void]$titleOperators.Add($operator) } } # Analytic rule ID conditions if ($propertyName -match 'AnalyticRuleIds') { $value = $cond.conditionProperties.propertyValues if ($value -is [System.Array]) { foreach ($item in $value) { if (-not [string]::IsNullOrWhiteSpace("$item")) { [void]$ruleIdFilters.Add("$item") } } } elseif (-not [string]::IsNullOrWhiteSpace("$value")) { [void]$ruleIdFilters.Add("$value") } } } [PSCustomObject]@{ AutomationRuleId = $rule.name DisplayName = $props.displayName Enabled = [bool]$props.isEnabled Order = [int]$props.order TriggersOn = $props.triggeringLogic.triggersOn TriggersWhen = $props.triggeringLogic.triggersWhen IsCloseIncidentRule = $null -ne $closeAction HasConditions = $hasConditions TitleFilters = @($titleFilters | Select-Object -Unique) TitleOperators = @($titleOperators) RuleIdFilters = @($ruleIdFilters | Select-Object -Unique) Conditions = $conditions Actions = $actions Raw = $rule } } @($normalized) } |