Azure Azure Monitor Azure PowerShell

Create an Azure Monitor action group with Azure PowerShell

[November 26, 2019 – Original post]


Azure Monitor, Microsoft’s built-in monitoring service, allows you to monitor and gain more visibility into the state of your resources from a single place. In this way this service can help you to quickly find and fix problems.

To notify users that an alert has been triggered, Azure Monitor and also other services like Azure Service Health and Azure Advisor, use action groups. Action groups allow an owner of an Azure subscription or an Azure Administrator with the proper role-based access control (RBAC) permissions to group a collection of actions to take when an alert is triggered. They can create an action group with functions such as sending an email, SMS, Logic or Function App, as well as calling a webhook and re-use it across multiple alerts. Various alerts may use the same action group or different action groups depending on the user’s requirements.

If you’re interested, you can always find more information about an action group on this Microsoft Docs page


Action groups can be created through the Azure portal, but to automate the process you can also use Azure PowerShell. In the below script a new action group is created, which will notify the added people (email address or addresses) by email whenever a specific event is triggered. For example, you can then alert on metrics and logs, like Activity Log events, log search queries, or even the health of the underlying Azure platform (service issues). For the moment, you may have up to 1000 email actions in an action group. Also ensure that your email filtering is configured appropriately.

The Azure PowerShell script I wrote to automate the creation of this action group, will do all of the following:

  • Check if the PowerShell window is running as Administrator (when not running from Cloud Shell), otherwise the Azure PowerShell script will be exited.
  • Suppress breaking change warning messages.
  • Store the specified set of tags in a hash table.
  • Set and add tags with the specified key/value pairs into the proper data type (dictionary object instead of a hash table).
  • Create a resource group for the Action Group resource, if it not already exists. Add specified tags.
  • Create a new action group Email receiver in memory.
  • Create a new or update the existing action group.
  • Lock the Action Group resource group with a CanNotDelete lock.


To use the script copy and save it as Create-Azure-Monitor-Action-Group.ps1 or download it from GitHub.  Then before using the script, adjust all variables to your use (you can find an adjusted example in the screenshot below) and then run the customized script with Administrator privileges from Windows TerminalVisual Studio Code, or Windows PowerShell. Or you can simply run it from Cloud Shell.



Prerequisites

  • An Azure Subscription.
  • An Azure Administrator account with the necessary RBAC roles.


Azure PowerShell script

If you are not running the script from Cloud Shell, don’t forget to sign in with the Connect-AzAccount cmdlet to connect your Azure account. And if you are using multiple Azure subscriptions, select the proper subscription with the Get-AzSubscription cmdlet before running the script.


<#
.SYNOPSIS

A script used to create an Azure Monitor action group.

.DESCRIPTION

A script used to used to create an Azure Monitor action group with the Email action type.
This script will do all of the following:

Check if the PowerShell window is running as Administrator (which is a requirement), otherwise the Azure PowerShell script will be exited.
Suppress breaking change warning messages.
Store the specified set of tags in a hash table.
Set and add tags with the specified key/value pairs into the proper data type (dictionary object instead of a hash table) to be able to use them with an Action Group.
Create a resource group for the action group resource, if it not already exists. Add specified tags.
Create a new action group Email receiver in memory.
Create a new or update the existing action group.
Lock the Action Group resource group with a CanNotDelete lock.

.NOTES

Filename:       Create-Azure-Monitor-Action-Group.ps1
Created:        26/11/2019
Last modified:  23/06/2022
Author:         Wim Matthyssen
Version:        2.0
PowerShell:     Azure Cloud Shell or Azure PowerShell
Version:        Install latest Azure Powershell modules
Action:         Change variables were needed to fit your needs. 
Disclaimer:     This script is provided "As Is" with no warranties.

.EXAMPLE

Connect-AzAccount
.\Create-Azure-Monitor-Action-Group.ps1

.LINK

https://wmatthyssen.com/2019/11/26/create-an-azure-monitor-action-group-with-azure-powershell/
#>

## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Variables

$spoke = "hub"
$purpose = "monitor"

$rgActionGroup = #<your action group rg here> The name of the resource group in which the action group is saved. Example: "rg-hub-myh-management"
$actionGroupName = #<your action group name here> The name of the action group. Example: "ag-hub-myh-admin"
$actionGroupShortName = #<your action group display name here> The name used when notifications are sent using this group, max 12 characters long. Example: "ag-admin"
$emailReceiverName = "emailreceiver"
$emailAddress = #<your email address here> The email address you want to use. Example: "test@demo.com"

$tagSpokeName = #<your environment tag name here> The environment tag name you want to use. Example:"Env"
$tagSpokeValue = "$($spoke[0].ToString().ToUpper())$($spoke.SubString(1))"
$tagCostCenterName  = #<your costCenter tag name here> The costCenter tag name you want to use. Example:"CostCenter"
$tagCostCenterValue = #<your costCenter tag value here> The costCenter tag value you want to use. Example: "23"
$tagCriticalityName = #<your businessCriticality tag name here> The businessCriticality tag name you want to use. Example:"Criticality"
$tagCriticalityValue = #<your businessCriticality tag value here> The businessCriticality tag value you want to use. Example: "High"
$tagPurposeName  = #<your purpose tag name here> The purpose tag name you want to use. Example:"Purpose"
$tagPurposeValue = "$($purpose[0].ToString().ToUpper())$($purpose.SubString(1))" 

$global:currenttime= Set-PSBreakpoint -Variable currenttime -Mode Read -Action {$global:currenttime= Get-Date -UFormat "%A %m/%d/%Y %R"}
$foregroundColor1 = "Red"
$foregroundColor2 = "Yellow"
$writeEmptyLine = "`n"
$writeSeperatorSpaces = " - "

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Check if PowerShell runs as Administrator (when not running from Cloud Shell), otherwise exit the script

if ($PSVersionTable.Platform -eq "Unix") {
    Write-Host ($writeEmptyLine + "# Running in Cloud Shell" + $writeSeperatorSpaces + $currentTime)`
    -foregroundcolor $foregroundColor1 $writeEmptyLine
    
    ## Start script execution    
    Write-Host ($writeEmptyLine + "# Script started. Without any errors, it will need around 1 minute to complete" + $writeSeperatorSpaces + $currentTime)`
    -foregroundcolor $foregroundColor1 $writeEmptyLine 
} else {
    $currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
    $isAdministrator = $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

        ## Check if running as Administrator, otherwise exit the script
        if ($isAdministrator -eq $false) {
        Write-Host ($writeEmptyLine + "# Please run PowerShell as Administrator" + $writeSeperatorSpaces + $currentTime)`
        -foregroundcolor $foregroundColor1 $writeEmptyLine
        Start-Sleep -s 3
        exit
        }
        else {

        ## If running as Administrator, start script execution    
        Write-Host ($writeEmptyLine + "# Script started. Without any errors, it will need around 1 minute to complete" + $writeSeperatorSpaces + $currentTime)`
        -foregroundcolor $foregroundColor1 $writeEmptyLine 
        }
}

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Suppress breaking change warning messages

Set-Item Env:\SuppressAzurePowerShellBreakingChangeWarnings "true"

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Store the specified set of tags in a hash table

$tags = @{$tagSpokeName=$tagSpokeValue;$tagCostCenterName=$tagCostCenterValue;$tagCriticalityName=$tagCriticalityValue;$tagPurposeName=$tagPurposeValue}

Write-Host ($writeEmptyLine + "# Specified set of tags available to add" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine 

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Set and add tags with the specified key/value pairs into the proper data type (dictionary object instead of a hash table) to be able to use them with an Action Group

$tagsActionGroup = New-Object "System.Collections.Generic.Dictionary``2[System.String,System.String]"
$tagsActionGroup.Add($tagSpokeName,$tagSpokeValue)
$tagsActionGroup.Add($tagCostCenterName,$tagCostCenterValue)
$tagsActionGroup.Add($tagCriticalityName,$tagCriticalityValue)
$tagsActionGroup.Add($tagPurposeName,$tagPurposeValue)

Write-Host ($writeEmptyLine + "# Tags set into the proper data type" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine 

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Create a resource group for the action group resource, if it not already exists. Add specified tags

try {
    Get-AzResourceGroup -Name $rgActionGroup -ErrorAction Stop | Out-Null
} catch {
    New-AzResourceGroup -Name $rgActionGroup.ToLower() -Location $region -Force | Out-Null
}

# Set tags Bastion resource group
Set-AzResourceGroup -Name $rgActionGroup -Tag $tags | Out-Null

Write-Host ($writeEmptyLine + "# Resource group $rgActionGroup available" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Create a new action group Email receiver in memory 

$email1 = New-AzActionGroupReceiver -Name $emailReceiverName -EmailReceiver -EmailAddress $emailAddress 

Write-Host ($writeEmptyLine + "# Action Group Receiver $emailReceiverName saved in memory" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine 

## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Create a new or update the existing action group

Set-AzActionGroup -Name $actionGroupName -ResourceGroup $rgActionGroup -ShortName $actionGroupShortName -Receiver $email1 -Tag $tagsActionGroup | Out-Null 

Write-Host ($writeEmptyLine + "# Action Group $actionGroupName created" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine 

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Lock the Action Group resource group with a CanNotDelete lock

$lock = Get-AzResourceLock -ResourceGroupName $rgActionGroup

if ($null -eq $lock){
    New-AzResourceLock -LockName DoNotDeleteLock -LockLevel CanNotDelete -ResourceGroupName $rgActionGroup -LockNotes "Prevent $rgActionGroup from deletion" -Force | Out-Null
    } 

Write-Host ($writeEmptyLine + "# Resource group $rgActionGroup locked" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Write script completed

Write-Host ($writeEmptyLine + "# Script completed" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine 

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------





You can check all existing action groups in your subscription, by running the below cmdlet. In my example the previously created action group ag-hub-myh-admin is shown.

## View available action groups

Get-AzActionGroup | Select-Object Name


You can also add, validate or manage action groups through the Azure portal by opening Monitor, selecting Alerts and selecting Action groups




I hope this Azure PowerShell script comes in handy whenever you need to create a new action group in your own Azure environment.

If you have any questions or recommendations about it, feel free to contact me through my Twitter handle (@wmatthyssen) or to just leave a comment.


7 comments on “Create an Azure Monitor action group with Azure PowerShell

  1. Pingback: Azure Service Health: How to create a pinned health world map and a service health alert – Wim Matthyssen

  2. Pingback: Azure Advent Calendar 2019 – Azure Service Health – Wim Matthyssen

  3. Pingback: Azure Service Health: Remain informed about Azure service issues, planned maintenance, health and security advisories - MC2MC

  4. Hi, how did you make your Powershell show the lightning icon and coloured highlight?

    Like

Leave a Reply to wmatthyssen Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: