I found it rather difficult to create an alert rule using PowerShell as opposed to using Azure CLI. That's why I thought it is worth a post.
In the following tiny howto, we are going to create an alert that gets triggered when the average CPU load of a virtual machine stays above 90% for a duration of 5 minutes. I assume there exists a resource group called
rg-training and a virtual machine named
In general, an alert rule consists of the following components.
|Scope||The resource(s) you want to monitor|
|Condition||Configures when the alert rule should trigger the action|
|Action Group||A list of actions to invoke when the alert rule triggers (optional)|
|Alert Rule Details||Some identification information|
First, we need to create an action group that we later are going to use with the alert rule. This rule will send an email to defined recipients upon the rule triggers.
# Create an action group az monitor action-group create \ --name notify-admins \ --resource-group rg-training \ --action email my-action-name [email protected]
Have a look at
az monitor action-group create -hfor further actions that are available. For example you can also send out an SMS, trigger a webhook and so on.
Then we need to retrieve the ID of the virtual machine and store it for later use...
# Retrieve VM identifier used for scope parameter $scope = az vm show \ --name vm1 \ --output tsv \ --query id
Finally, we create a metric alert, that will trigger when the average CPU load stays above 90% for a duration of 5 minutes (measured once per minute).
# Create the actual alert az monitor metrics alert create \ --name alert2 \ --resource-group rg-training \ --scopes $scope \ --condition "avg Percentage CPU > 90" \ --window-size 5m \ --evaluation-frequency 1m \ --action notify-admins \ --description "High CPU"
That was easy. Now let's have a look at the PowerShell variant, where things are a bit more complicated and long-winded.
First, we need to create an action group receiver object and an action group.
# Creates an new action group receiver object in memory $receiver = New-AzActionGroupReceiver ` -Name "Admin" ` -EmailAddress "[email protected]" # Creates a new or updates an existing action group. $actionGroup = Set-AzActionGroup ` -Name "notify-admins" ` -ShortName "ActionGroup1" ` -ResourceGroupName "rg-training" ` -Receiver $receiver
Have a look at the official documentation for further receivers that can be configured.
Now let's read back the action group and store it in a variable.
# Creates an ActionGroup reference object in memory. $actionGroupId = New-AzActionGroup -ActionGroupId $actionGroup.Id
$actionGroupIdwill hold an object of type
ActivityLogAlertActionGroupthat is later required for the
Okay great! now we need a condition.
# Creates a local criteria object that can be used to create a new metric alert $condition = New-AzMetricAlertRuleV2Criteria ` -MetricName "Percentage CPU" ` -TimeAggregation Average ` -Operator GreaterThan ` -Threshold 0.1
And finally, we can put all the pieces together and call
Add-AzMetricAlertRuleV2 as follows.
$windowSize = New-TimeSpan -Minutes 1 $frequency = New-TimeSpan -Minutes 1 $targetResourceId = (Get-AzResource -Name VM1).ResourceId # Adds or updates a V2 (non-classic) metric-based alert rule. Add-AzMetricAlertRuleV2 ` -Name "metricRule" ` -ResourceGroupName "rg-training" ` -WindowSize $windowSize ` -Frequency $frequency ` -TargetResourceId $targetResourceId ` -Condition $condition ` -ActionGroup $actionGroupId ` -Severity 3
Add-AzMetricAlertRuleV2 throws an exception at you like the one below, then make sure you are using the correct metric name.
Add-AzMetricAlertRuleV2: Exception type: ErrorResponseException, Message: Couldn't find a metric named <some_metric_you_entered>. Make sure the name is correct. Activity ID: <some-guid>., Code: BadRequest, Status code:BadRequest, Reason phrase: BadRequest
You can look up the correct metric names by issuing the cmdlet below. Make sure you replace the metric namespace with the resource type and ID of your choice.
# Gets metric definitions $validMetrics = Get-AzMetricDefinition ` -MetricNamespace "Microsoft.Compute/virtualMachine" ` -ResourceId $targetResourceId) # Get the values $validMetrics.Name
Or alternatively, look them up in the documentation 😉That's it for today. I hope you enjoyed this post. Happy hacking! 😎