Microsoft Sentinel comes with analytics rule built-in templates that you can turn into active analytic rules by effectively creating a copy of them – that’s what happens when you create a rule from a template.
What if you have a large number of analytics rule templates?
In this article, we will share with you how to create and enable Microsoft Sentinel Analytics Rules at scale using PowerShell, this is very useful if you have many Analytics Rule templates and you want to enable them at once, this will save thousands of mouse clicks.
Table of Contents
Introduction
Microsoft Sentinel is a cloud-native Security Information Event Management (SIEM) and Security Orchestration Automated Response (SOAR) solution. Microsoft Sentinel delivers intelligent security analytics and threat intelligence across the enterprise, providing a single solution for alert detection, threat visibility, proactive hunting, and threat response.
Microsoft Sentinel Analytics Rules templates were designed by Microsoft’s team of security experts and analysts based on known threats, common attack vectors, and suspicious activity escalation chains. Many of these templates can be customized to search for activities, or filter them out, according to your needs.
Solutions in Microsoft Sentinel Content Hub provide a consolidated way to acquire Microsoft Sentinel content, like data connectors, workbooks, analytics, and automation, in your workspace with a single deployment step.
The question that comes often is, what if we have imported a solution from Content Hub that has more than 40 Analytics rules and we need to create rules from these templates?

As you probably know, this is a tedious operation to do in the Azure portal.
Let’s see how to automate this process and detect threats faster by creating and enabling the Microsoft Sentinel built-in rules at scale.
Prerequisites
To follow this article, you need to have the following:
1) Azure subscription – If you don’t have an Azure subscription, you can create a free one here.
2) Log Analytics workspace – To create a new workspace, follow the instructions here Create a Log Analytics workspace.
3) Enable Microsoft Sentinel at no additional cost on an Azure Monitor Log Analytics workspace for the first 31 days, follow the instructions here. Once Microsoft Sentinel is enabled on your Azure Monitor Log Analytics workspace, every GB of data ingested into the workspace can be retained at no charge for the first 90 days.
4) Azure PowerShell installed locally on your machine or using the Cloud Shell.
5) The Azure Resource Graph module for PowerShell. Please note that this module can be used with locally installed PowerShell, with Azure Cloud Shell, or with the PowerShell Docker image.
To install Azure Resource Graph and Azure Accounts PowerShell modules on your machine, you can run the following command:
# Install and update to the latest Az PowerShell module
Install-Module -Name Az.Accounts,Az.ResourceGraph -AllowClobber -Force
# Check Az PowerShell modules version installed
Get-Module -Name Az.Accounts,Az.ResourceGraph -ListAvailable | Select Name, Version
6) Make sure that the solution is installed from Content Hub first before you run the script described below. However, there are some default Analytics rules that already exist without installing any solution from Content Hub. In this case, you can also run the script by targeting the Source name that you see in the Rule templates tab under the Analytics page as shown in the figure below.

Enable Microsoft Sentinel Analytics Rules
You have a couple of options to run the script, you can either use Azure Cloud Shell, Visual Studio Code, or Windows Terminal. The Script works with PowerShell 5.1 or PowerShell 7 (core) with the Az module.
.EXAMPLE
.\Set-AnalyticsRules -SubscriptionId "xxxxxxxx-aaaa-bbbb-cccc-zzzzzzzzzzzz" -ResourceGroup "RG-Name" `
-WorkspaceName "Log-Analytics-Name" -SolutionName "Source-Name" -enableRules [Yes] -Verbose
This example will connect to your Azure account using the subscription Id specified, and then create all analytics rules from templates for the specified Microsoft Sentinel solution name (E.g SAP, Cloudflare, Dynamics 365, Azure Activity, or Azure Active Directory).
By default, all of the rules will be created in a Disabled state, however, you have the option to enable the rules at creation time as well by setting the parameter (enable rules) to Yes.
Here is an example of the output once you run this tool:

PowerShell Code
The complete script is detailed below to automate the entire creation process of Analytics Rules:
<#
.SYNOPSIS
Enable Microsoft Sentinel Analytics Rules at Scale.
.DESCRIPTION
How to create and enable Microsoft Sentinel Analytics Rules at Scale using PowerShell.
.NOTES
File Name : Set-AnalyticsRules.ps1
Author : Microsoft MVP/MCT - Charbel Nemnom
Version : 1.0
Date : 24-October-2022
Updated : 25-October-2022
Requires : PowerShell 5.1 or PowerShell 7.2.x (Core)
Module : Az Module & Az Resource Graph
.LINK
To provide feedback or for further assistance please visit: https://charbelnemnom.com
.EXAMPLE
.\Set-AnalyticsRules.ps1 -SubscriptionId "SUB-ID" -ResourceGroup "RG-Name" `
-WorkspaceName "Log-Analytics-Name" -SolutionName "Source-Name" -enableRules [Yes] -Verbose
This example will connect to your Azure account using the subscription Id specified, and then create all analytics rules from templates for the specified Microsoft Sentinel solution.
By default, all of the rules will be created in a Disabled state. You have the option to enable the rules at creation time by setting the parameter -enableRules [Yes].
#>
param (
[Parameter(Position = 0, Mandatory = $true, HelpMessage = 'Enter Azure Subscription ID')]
[string]$subscriptionId,
[Parameter(Position = 1, Mandatory = $true, HelpMessage = 'Enter Resource Group Name where Microsoft Sentinel is deployed')]
[string]$resourceGroupName,
[Parameter(Position = 2, Mandatory = $true, HelpMessage = 'Enter Log Analytics Workspace Name')]
[string]$workspaceName,
[Parameter(Position = 3, Mandatory = $true, HelpMessage = 'Enter Microsoft Sentinel Solution Name')]
[string]$solutionName,
[ValidateSet("Yes", "No")]
[String]$enableRules = 'No'
)
#! Install Az Module If Needed
function Install-Module-If-Needed {
param([string]$ModuleName)
if (Get-Module -ListAvailable -Name $ModuleName) {
Write-Host "Module '$($ModuleName)' already exists, continue..." -ForegroundColor Green
}
else {
Write-Host "Module '$($ModuleName)' does not exist, installing..." -ForegroundColor Yellow
Install-Module $ModuleName -Force -AllowClobber -ErrorAction Stop
Write-Host "Module '$($ModuleName)' installed." -ForegroundColor Green
}
}
#! Install Az Resource Graph Module If Needed
Install-Module-If-Needed Az.ResourceGraph
#! Install Az Accounts Module If Needed
Install-Module-If-Needed Az.Accounts
#! Check Azure Connection
Try {
Write-Verbose "Connecting to Azure Cloud..."
Connect-AzAccount -ErrorAction Stop | Out-Null
}
Catch {
Write-Warning "Cannot connect to Azure Cloud. Please check your credentials. Exiting!"
Break
}
$rgQuery = @"
resources
| where type =~ 'Microsoft.Resources/templateSpecs/versions'
| where tags['hidden-sentinelContentType'] =~ 'AnalyticsRule' and tags['hidden-sentinelWorkspaceId'] =~ '/subscriptions/$subscriptionid/resourceGroups/$resourceGroupName/providers/Microsoft.OperationalInsights/workspaces/$workspaceName'
| extend workspaceName = strcat(split('/subscriptions/$subscriptionid/resourceGroups/$resourceGroupName/providers/Microsoft.OperationalInsights/workspaces/$workspaceName', "/")[-1],'-')
| extend versionArray=split(id, "/")
| extend content_kind = tags['hidden-sentinelContentType']
| extend version = name
| extend parsed_version = parse_version(version)
| extend resources = parse_json(parse_json(parse_json(properties).template).resources)
| extend metadata = parse_json(resources[array_length(resources)-1].properties)
| extend contentId=tostring(metadata.contentId)
| summarize arg_max(parsed_version, version, properties) by contentId
| project contentId, version, properties
| mv-expand solution = properties.template.resources
| where solution.properties.source.name == '$($solutionName)'
| project-away solution
"@
Write-Output $rgQuery
try {
$templates = Search-AzGraph -Query $rgQuery
if ($templates.Count -eq 0) {
throw "Resource Graph query error"
}
}
catch {
Write-Error $_ -ErrorAction Stop
}
foreach ($template in $templates) {
$ruleId = $template.contentId
$rule = $template.properties.template.resources | Where-Object type -eq 'Microsoft.SecurityInsights/AlertRuleTemplates' | Select-Object kind, properties
$rule.properties | Add-Member -NotePropertyName alertRuleTemplateName -NotePropertyValue $ruleId
$rule.properties | Add-Member -NotePropertyName templateVersion -NotePropertyValue $template.version
If ($enableRules -eq "Yes") {
$rule.properties.enabled = $true
}
$payload = $rule | ConvertTo-Json -Depth 100
$apiPath = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.OperationalInsights/workspaces/$workspaceName/providers/Microsoft.SecurityInsights/alertRules/$($ruleId)?api-version=2022-09-01-preview"
try {
$result = Invoke-AzRestMethod -Method PUT -path $apiPath -Payload $payload
If ($enableRules -eq "Yes") {
Write-Verbose "Creating and Enabling rule $($rule.properties.displayName)"
}
Else {
Write-Verbose "Creating rule $($rule.properties.displayName)"
}
if (!($result.StatusCode -in 200, 201)) {
Write-Host $result.StatusCode
Write-Host $result.Content
throw "Error when enabling Analytics rule $($rule.properties.displayName)"
}
}
catch {
Write-Error $_ -ErrorAction Continue
}
}
Before running the tool, we can see that we don’t have any active rules created in the Disabled state. In this example, we have 15 Active rules only.

Once you run this tool, you can refresh the Analytics rules page and check all the rules are created in the Disabled state. In this example, we have 58 Active rules.

That’s it there you have it. Happy Analytics Rules creation with Microsoft Sentinel!
If you have any feedback or changes that everyone should receive, please feel free to leave a comment below.
Summary
This article showed you how to create and enable Microsoft Sentinel Analytics Rules at scale using PowerShell, this is very useful if you have many Analytics Rule templates as part of a Content Hub solution and you want to enable them at once.
Analytics rules search for specific events or sets of events across your environment, alert you when certain event thresholds or conditions are reached, generate incidents for your SOC to triage and investigate, and respond to threats with automated tracking and remediation processes.
This is one of the many features in Microsoft Sentinel that can be utilized to provide immense value to threat detection out-of-the-box.
The power of Microsoft Sentinel comes from the ability to detect, investigate, respond to, and remediate threats.
__
Thank you for reading my blog.
If you have any questions or feedback, please leave a comment.
-Charbel Nemnom-
Hello,
This looks very interesting. I tried to run the script however it returns no results.
With all the Microsoft changes, I was wondering if the script still works.
Thank you.
Hello Csaba, thank you for the comment!
Yes, the script is still working 100 percent. I just tested it again and I confirm that it’s working.
If you could provide more details so I can help.
Which Solution Name are you trying to enable the Analytic Rules for?
Thanks!
Hello,
thank you for your reply. I am getting the following result when trying to run the script:
(I have edited some of the information with REDACTED)
resources
| where type =~ ‘Microsoft.Resources/templateSpecs/versions’
| where tags[‘hidden-sentinelContentType’] =~ ‘AnalyticsRule’ and tags[‘hidden-sentinelWorkspaceId’] =~ ‘/subscriptions/REDACTED/resourceGroups/REDACTED/providers/Microsoft.OperationalInsights/workspaces/REDACTED’
| extend workspaceName = strcat(split(‘/subscriptions/REDACTED/resourceGroups/REDACTED/providers/Microsoft.OperationalInsights/workspaces/REDACTED’, “/”)[-1],’-‘)
| extend versionArray=split(id, “/”)
| extend content_kind = tags[‘hidden-sentinelContentType’]
| extend version = name
| extend parsed_version = parse_version(version)
| extend resources = parse_json(parse_json(parse_json(properties).template).resources)
| extend metadata = parse_json(resources[array_length(resources)-1].properties)
| extend contentId=tostring(metadata.contentId)
| summarize arg_max(parsed_version, version, properties) by contentId
| project contentId, version, properties
| mv-expand solution = properties.template.resources
| where solution.properties.source.name == ‘Azure Active Directory’
| project-away solution
VERBOSE: Sent top=100 skip=0 skipToken=
VERBOSE: Received results: 0
C:\Tools\Sentinel\Set-AnalyticsRules.ps1 : Resource Graph query error
At line:1 char:1
+ .\Set-AnalyticsRules.ps1 -subscriptionId REDACTED …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Set-AnalyticsRules.ps1
Thank you.
Hello Csaba, thanks for sharing the details!

I have noticed that you are trying to enable the “Azure Active Directory” Analytics Rules as a solution from Content Hub, right?
I just exactly simulated your scenario and I was able to create all the 48 Analytics rules for “Azure Active Directory” successfully as shown in the screenshot below.
What I see based on the error you shared above, it looks like you have a write permissions issue.
I supposed that you launched PowerShell with admin rights as well.
Could you please verify your Azure and Microsoft Sentinel permissions?
Hope it helps!
Hello, I tried this from the Azure Cloud Shell, however, it errors with:
Exception: Resource Graph query error.
I ran:
clouddrive> ./enableanalytics.ps1 -SubscriptionId “REMOVED” -ResourceGroup “my-sandbox” -WorkspaceName “sentineltest” -SolutionName “Azure Active Directory” -Verbose
I did also run:
Install-Module -Name Az.Accounts, Az.ResourceGraph -AllowClobber -Force
Get-Module -Name Az.Accounts, Az.ResourceGraph -ListAvailable | Select Name, Version
Name Version
—- ——-
Az.Accounts 2.11.1
Az.Accounts 2.9.1
Az.ResourceGraph 0.13.0
Az.Accounts 2.11.0
Have you seen the same error?
Hello Darren, thanks for the comment!
I am seen that you are running this from Azure Cloud Shell.
Are you using the Sandbox environment from Microsoft Learn to test this, or do you have a private subscription from Sentinel?
Could you please try to run it from your local machine instead of using Cloud Shell?
Let me know if it works.
Hey there, this solution seems to work consistently for the Azure Active Directory connector, however, trying to enable rules for any other data connector seems to fail. Office 365 for example, or even Microsoft Defender for Cloud or any other Microsoft Data Connector.
Is there perhaps something in the code that is specifically pointed at Azure Active Directory Data Connector?
Hello Nick, thanks for the comment!


Please note that this solution works consistently on any source name that you provide in Sentinel.
I am using the code exactly as provided in this article.
I have just tested it with the Source name “Microsoft 365 Defender”, and “Dynamics 365” solutions. It’s working flawlessly.
Please find below screenshots for your reference confirming the same.
1) Running the script to create “Microsoft 365 Defender” Analytic Rules.
2) Confirming “Microsoft 365 Defender” Analytic Rules are created in a Disabled state.
Hope it helps!
Hi,
What if I wanted to enable all 483 default Rule templates from Gallery Content?
The Source name for these, are known as “Gallery Content”
.\Set-AnalyticsRules.ps1 -SubscriptionId “xxxxxxxxxxxxxxxxxx” -ResourceGroupName “SOC” -WorkspaceName “SOC-AZURE” -SolutionName “Gallery Content” -enableRules No -Verbose
Hello Yap, thanks for the comment!
I’ve checked the Rule templates in the Gallery Content, and the source name is called “galleryContent” one word.
Could you please retry using the following command:
Let me know if it works for you.
I am getting an error “Exception: Resource Graph query error”
not sure where is failing. I am following the script, trying ‘Azure Active Directory’ or ‘Azure Firewall’ – the same.
Any help on this?
Much appreciated
Hello Ermir, thanks for the comment! This is really very strange.
I just ran the same script now and I was able to create all the 48 Analytics Rules of ‘Azure Active Directory’.
What is the version of the Az.ResourceGraph loaded on your machine?
I have version 0.13.0 installed.
I would suggest that you run the script manually portion by portion and see where it’s failing.
Let me know if it works for you.
Hi Charbel,
Thanks for your great work – I really enjoy reading your blog posts.
I’m just wondering whether you know of any solution/script capable of:
– automatically deploying all of the “analytic rule templates” which come with MS Sentinel, by default.
Ideally- the script/solution would have the ability to either:
– Take 1 or more template IDs parameters- to deploy only a subset of the total templates, OR
– Pass in a “data connector” parameter- which would only deploy analytic rules- associated with that data connector?
—————————
Alternatively – do you know of any way to automate the “updating” of existing analytic rules- when Microsoft updates the KQL?
Thanks in advance,
Ryan
Hi Charbel, thanks very much for this script, it has helped a lot on a few engagements to date.
As Ermir mentioned, I also had the same error. The missing piece for me was to make sure that the solution is installed from Content Hub.
In my case, I had been enabling rules for a colleague who had already installed the solutions. On this occasion I had done the full deployment, therefore missed installing the solution itself – if that makes sense?
Hello Stuart, thanks for the comment and feedback!
Yes, you are right. You need to have the solution in question installed from Content Hub first before you run the script.
However, there are some default Analytics rules that already exist without installing any solution from Content Hub.
In this case, you can also run the script by targeting the Source name that you see in the Rule templates tab under Analytics.
I have updated the article to clarify that point as prerequisite #6.
Thanks!
Hello Ryan O, thanks for the comment and feedback!
I am happy to hear that you’re enjoying reading my blog posts.
Yes, there is a PowerShell script that you can use to automate the “UPDATE AVAILABLE” of existing analytic rules – when Microsoft updates the KQL.
This script was written by a Microsoft Team Member in Customer Experience Engineering (CxE) Team.
I just tested it and it works. You can access it on this page.
Disclaimer before you use it: This will update ALL the analytic rules where the rule template has been updated, and be aware if you have some custom modifications in those templates. They might get overwritten. So, use it at your own risk!
This script will update all the Analytic rules that come from a rule template that has been updated and they are enabled (active).
Now you can go a step further instead of running this script manually every time, you can use Azure Automation and schedule the script to run automatically twice per month for example, to update all your rules.
—————————
In regards to your other questions:
– automatically deploying all of the “analytic rule templates” which come with MS Sentinel, by default.
Yes, you can use my script as described in this article and pass the -SolutionName as “galleryContent” one word.
Hope it helps and let me know if it works for you!
***Slight amendment to my original reply sent about 5 mins before this one*** where I accidentally typed “Gallery Content” instead of “galleryContent” when indicating the failed command I ran
Hi Charbel,
Thanks for responding so quickly.
Your script seems to work perfectly when I use: i) “Azure Active Directory” or ii) “Microsoft 365 Defender” as the -SolutionName. However, it does not work for me when I try using -SolutionName “galleryContent” to install “all” the analytic rules templates.
The full (redacted) command I tried was: `.\Set-AnalyticRules.ps1 -SubscriptionId -ResourceGroup -WorkspaceName -SolutionName “galleryContent” -enableRules No -Verbose `
Note 1: I have also tried: i) -SolutionName “Gallery Content”, ii) -SolutionName “GalleryContent” and both of these also fail
Note 2: I have also tried excluding the – enableRules parameter – and this also didn’t work
————————–
Q1) Similarly to how I had to install the “Azure Active Directory” and “Microsoft 365 Defender” solutions before running the command for these solutions- is there anything I need to install as a pre-requisite before running the -SolutionName “galleryContent” cmd?
Q2) Do you have any other ideas on why this may be failing. (The account I’m using to authenticate to Azure AD has global admin permissions in the tenant, and then: i) “owner”, ii) “Sentinel Contributor” and iii) “Sentinel Automation Contributor” permissions on the resource group
Hello Ryan,
Please note that you need to have the solution in question installed from Content Hub first before you run the script.
You mentioned that when you use: i) “Azure Active Directory” or ii) “Microsoft 365 Defender” as the -SolutionName it works.
Did you try to install any other solution from Content Hub and then try to target that solution specifically?
I need to double-check the “galleryContent” as a solution if it works, but for any other solution that you install from Content Hub, it should work without any issues.
Thanks!
Hi Charbel,
– I also tried -SolutionName “Syslog”. This worked perfectly
– I also tried -SolutionName “Cisco Umbrella”. This failed. However, it worked when I used -SolutionName “CiscoUmbrella”.
From this- I can deduce:
1. That naming convention matters. And therefore- you need some way of knowing/guessing how the SolutionName should be formatted. For example, the -SolutionName for any Microsoft solutions is straightforward because they appear to exactly match the solution name in the Content hub. However, for Cisco- the content hub solution name is “Cisco Umbrella” which is a space in between. However, in your script the -SolutionName needs to be “CiscoUmbrella” without the space in between.
2. Based on the above- I suspect that -SolutionName “galleryContent” is might be failing because the formatting/casing of “galleryContent” may be incorrect.
Let me know what you think?
Cheers,
Ryan
Hello Ryan, I looked at this more deeply.

Unfortunately, the default “galleryContent” as a solution cannot be activated/enabled today using this script.
Those are not coming from a Content Hub solution, therefore we cannot find them in Resource Graph as templates.
I am still looking for a solution to this.
—————
Now about your second question ‘naming convention’, I checked it and you can get the correct Solution Name by looking at the Rule Templates tab, and filtering by Source Name as you can see in the screenshot below “CiscoUmbrella” without any spaces.
Once you identify the desired source name, then you can run the script and it should work 100%.
Hope it helps!