src/Set-AlertRules.ps1
function Set-AlertRules { [CmdLetBinding(SupportsShouldProcess)] [OutputType([PSCustomObject[]])] Param( [string][Parameter(Mandatory)]$ResourceGroup, [PsCustomObject[]][Parameter(Mandatory)]$AlertRules, [Parameter(Mandatory)]$ActionGroupReceiver, [switch][Parameter()]$DisableAlerts ) Set-StrictMode -Version Latest $resources = Get-AzResource -ResourceGroupName $ResourceGroup $overWrites = $AlertRules | where { "SpecialRuleType" -in $_.PsObject.Properties.Name -and $_.SpecialRuleType -eq "OVERWRITE" } $AlertRules = $AlertRules | where { "SpecialRuleType" -notin $_.PsObject.Properties.Name } function SeverityAsInt([string]$Severity) { switch ($Severity) { "Critical" { return 0 } "Error" { return 1 } "Warning" { return 2 } "Information" { return 3 } Default { throw "Invalid option for severity $Severity" } } } $PSCmdlet.ShouldProcess($ResourceGroup, "Set-AzActionGroup - azure-alerts") { $alertRef = Set-AzActionGroup ` -Name "azure-alerts" ` -ResourceGroup $ResourceGroup ` -ShortName "azure-alerts" ` -Receiver $ActionGroupReceiver ` -DisableGroup:$DisableAlerts ` -WarningAction SilentlyContinue # See https://github.com/Azure/azure-powershell/issues/9259 ... $alertRef = New-AzActionGroup -ActionGroupId $alertRef.Id } function ConcatStepTexts([string[]]$new, [string[]]$old, [string]$howToConcat) { switch ($howToConcat) { "Before" { return $new + $old } "After" { return $old + $new } "Replace" { return $new } Default { } } } function ApplyOverwrite([PsCustomObject]$mathingAlertRule, [PsCustomObject]$overWrite) { if ($overWrite.FixSteps) { $mathingAlertRule.AlertFixSteps = ConcatStepTexts $overWrite.FixSteps $mathingAlertRule.AlertFixSteps $overWrite.FixStepsLocation } if ($overWrite.ValidationSteps) { $mathingAlertRule.AlertValidationSteps = ConcatStepTexts $overWrite.ValidationSteps $mathingAlertRule.AlertValidationSteps $overWrite.ValidationStepsLocation } if ($overWrite.Severity) { $mathingAlertRule.Severity = $overWrite.Severity } if ($overWrite.Criteria) { $mathingAlertRule.Criteria = $overWrite.Criteria } if ($overWrite.WindowSize) { $mathingAlertRule.WindowSize = $overWrite.WindowSize } if ($overWrite.Frequency) { $mathingAlertRule.Frequency = $overWrite.Frequency } } function ResolveDescription([PsCustomObject]$mathingAlertRule, [PsCustomObject]$resource) { [System.Collections.ArrayList]$alertValidations = @() [System.Collections.ArrayList]$alertFixSteps = @() if ("AlertValidationSteps" -in $mathingAlertRule.PsObject.Properties.Name) { $alertValidations.AddRange($mathingAlertRule.AlertValidationSteps) } if ("AlertFixSteps" -in $mathingAlertRule.PsObject.Properties.Name) { $alertFixSteps.AddRange($mathingAlertRule.AlertFixSteps) } return "$($mathingAlertRule.Description) " + "$(if($alertValidations) {"Validation steps: $alertValidations /"}) " + "$(if($alertFixSteps) {"Fix steps: $alertFixSteps"})" } function FormatCriteriaObject([Microsoft.Azure.Commands.Insights.OutputClasses.PSMetricCriteria] $criteriaToSimplify, $rule) { return [PSCustomObject]@{ Metric = $criteriaToSimplify.MetricName Threshold = $criteriaToSimplify.Threshold Aggregation = $criteriaToSimplify.TimeAggregation WindowSize = $rule.WindowSize } } foreach ($resource in $resources) { Write-Verbose "Checking alert rules for resource $($resource.Id)" $matchingRules = $AlertRules | where { $_.ResourceType -eq $resource.ResourceType } foreach ($matchingRule in $matchingRules) { $applicapleOverwrites = $overWrites | where { $_.ResourceType -eq $matchingRule.ResourceType -and $_.Name -eq $matchingRule.Name } foreach ($overwrite in $applicapleOverwrites) { ApplyOverwrite $matchingRule $overWrite } $fullName = "$($matchingRule.Name)-$($resource.Name -replace '/','-')" $fullDescription = ResolveDescription $matchingRule $resource Write-Verbose "Applying alert rule $($matchingRule.Name) to $($resource.Id)" # There is very anonying warning that some namespace of class is going to change one day in future (which cannot be fixed atm). For that reason all warnings are suppressed. # This isn't ideal solution however (3>$null). $criteria = Invoke-Command -ScriptBlock $matchingRule.Criteria -InputObject $resource 3>$null if ($PSCmdlet.ShouldProcess($resource.Id, $fullName)) { Add-AzMetricAlertRuleV2 ` -Name $fullName ` -ResourceGroupName $ResourceGroup ` -WindowSize $matchingRule.WindowSize ` -Frequency $matchingRule.Frequency ` -TargetResourceScope $resource.ResourceId ` -TargetResourceType $resource.ResourceType ` -TargetResourceRegion $resource.Location ` -Description $fullDescription ` -Severity (SeverityAsInt $matchingRule.Severity) ` -Condition $criteria ` -ActionGroup $alertRef | Out-Null } [PsCustomObject]@{ Name = $fullName Resource = $resource.Id Description = $fullDescription Criteria = FormatCriteriaObject $criteria $matchingRule } } } } |