Updated – 13/08/2025 – The tool below has been updated to fix the incident and grouping configuration for the analytic rule template to validate the time span value in ISO 8601 format.
Updated – 06/05/2025 – The tool below has been updated to include a new option that excludes Preview and Deprecated Rule Templates from deployment and activation.
Updated – 01/05/2025 – The tool below has been updated to include a new option that allows you to exclude specific rule template names from deployment and activation.
Updated – 22/05/2024 – The tool below has been updated to include the MITRE ATT&CK “Sub techniques” for the analytic rule, which requires a preview API version in addition to the “Tactics” and “Techniques“.
Updated – 27/12/2023 – The tool below has been updated to identify all installed solutions; you need to enter and pass the name of the solution(s) [Content title] as shown in the Content Hub blade.
Updated – 25/10/2023 – The tool below has been updated to identify all installed solutions, despite the discrepancy between the solution name that you see in the Microsoft Sentinel portal and the API.
Updated – 15/10/2023 – The tool below has been updated to incorporate the recent API changes for Content Hub.
Updated – 28/07/2023 – The tool below has been updated to leverage Content Hub GA changes. The Resource Graph is being deprecated by Microsoft and replaced by the REST API.
Microsoft Sentinel comes with analytics rules built-in templates that you can turn into active analytics 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 often comes is, what if we have imported a solution from Content Hub that has more than 50 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 and Defender 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 to 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 90 days. You need to have at least Microsoft Sentinel Contributor rights.
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 the 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 -AllowClobber -Force
# Check Az PowerShell modules version installed
Get-Module -Name Az.Accounts -ListAvailable | Select Name, Version
6) Make sure that the solution is installed from Content Hub first before you run the script described below. However, some default Analytics rules 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 Gallery Content Analytics Rules
If you are interested in enabling and activating the default built-in rules, which are listed under the “galleryContent” as a source, then you need to use the native Microsoft Azure PowerShell – Microsoft Sentinel cmdlets (Az.SecurityInsights) in Windows PowerShell and PowerShell Core.
Here is an example of how you can enable the default Analytics Rules from the Gallery Content. Please note that for the solution(s) that you import from Content Hub, please refer to the next section.
#! 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 Security Insights Module If Needed
Install-Module-If-Needed Az.SecurityInsights
#! 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
}
#! For the Built-in Scheduled Analytics Rule Type, you can run the following command:
#! Get the list of all built-in Scheduled Analytics Rule Type
$scheduledRules = Get-AzSentinelAlertRuleTemplate -ResourceGroupName <RG-Name> -WorkspaceName <LogAnalytics-Name> | where Kind -EQ "Scheduled"
#! For the Built-in Microsoft Security Analytics Rule Type, you can run the following command:
#! Get the list of all built-in Microsoft Security Analytics Rule Type
$securityRules = Get-AzSentinelAlertRuleTemplate -ResourceGroupName <RG-Name> -WorkspaceName <LogAnalytics-Name> | where Kind -EQ "MicrosoftSecurityIncidentCreation"
#! For the Built-in Near Real-Time (NRT) Analytics Rule Type, you can run the following command:
#! Get the list of all built-in Near Real-Time (NRT) Analytics Rule Type
$nrtRules = Get-AzSentinelAlertRuleTemplate -ResourceGroupName <RG-Name> -WorkspaceName <LogAnalytics-Name> | where Kind -EQ "NRT"
#! For the Built-in Threat Intelligence Analytics Rule Type, you can run the following command:
#! Get the list of all built-in Threat Intelligence Analytics Rule Type
$tiRules = Get-AzSentinelAlertRuleTemplate -ResourceGroupName <RG-Name> -WorkspaceName <LogAnalytics-Name> | where Kind -EQ "ThreatIntelligence"
#! For the Built-in ML Behavior Analytics Rule Type, you can run the following command:
#! Get the list of all built-in ML Behavior Analytics Rule Type
$mlRules = Get-AzSentinelAlertRuleTemplate -ResourceGroupName <RG-Name> -WorkspaceName <LogAnalytics-Name> | where Kind -EQ "MLBehaviorAnalytics"
Let’s suppose you want to enable a specific built-in [Scheduled] – [Microsoft Defender XDR] Analytics Rule from the [Gallery Content], called “Multiple Teams deleted by a single user“, for example.
First, you need to identify the Alert Rule Template name, which is in GUID. You run the following command to get the GUID name:
#! Get the Alert GUID for "Multiple Teams deleted by a single user"
$AlertRuleTemplateName = Get-AzSentinelAlertRuleTemplate -ResourceGroupName <RG-Name> -WorkspaceName <LogAnalytics-Name> `
| where DisplayName -eq "Multiple Teams deleted by a single user"
#! Display the GUID Name
$AlertRuleTemplateName

Then you run the following PowerShell command to create and activate the “Scheduled” rule. Note that you need to pass the rule type (Kind), the rule template name (GUID), the severity, the KQL query, the frequency, and so on.
#! Create a Scheduled Analytics Rule "Multiple Teams deleted by a single user"
New-AzSentinelAlertRule -ResourceGroupName <RG-Name> -WorkspaceName <LogAnalytics-Name> `
-Kind $AlertRuleTemplateName.Kind -AlertRuleTemplateName $AlertRuleTemplateName.Name -enabled `
-Query $AlertRuleTemplateName.Query -Severity $AlertRuleTemplateName.Severity `
-DisplayName $AlertRuleTemplateName.DisplayName -QueryFrequency $AlertRuleTemplateName.QueryFrequency `
-QueryPeriod $AlertRuleTemplateName.QueryPeriod -TriggerOperator $AlertRuleTemplateName.TriggerOperator `
-TriggerThreshold $AlertRuleTemplateName.TriggerThreshold

Of course, you can build upon it and enable multiple built-in Analytics Rules from the Gallery Content. Please refer to the official documentation to see other examples of how to create or update the built-in Analytics Rule from the Gallery Content.
Enable Microsoft Sentinel Analytics Rules
This section will describe how to enable Microsoft Sentinel Analytics Rules for the solution(s) you import from Content Hub.
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-1
.\Set-AnalyticsRules.ps1 `
-SubscriptionId "xxxxxxxx-aaaa-bbbb-cccc-zzzzzzzzzzzz" `
-ResourceGroup "RG-Name" `
-WorkspaceName "Log-Analytics-Name" `
-SolutionName "Microsoft Entra ID" `
-enableRules Yes -Verbose
.EXAMPLE-2
.\Set-AnalyticsRules.ps1 `
-SubscriptionId "xxxxxxxx-aaaa-bbbb-cccc-zzzzzzzzzzzz" `
-ResourceGroup "RG-Name" `
-WorkspaceName "Log-Analytics-Name" `
-SolutionName "Azure SQL database" `
-enableRules Yes -Verbose
.EXAMPLE-3
.\Set-AnalyticsRules.ps1 `
-SubscriptionId "xxxxxxxx-aaaa-bbbb-cccc-zzzzzzzzzzzz" `
-ResourceGroup "RG-Name" `
-WorkspaceName "Log-Analytics-Name" `
-SolutionName "Windows Security Events" `
-enableRules Yes -Verbose
To supply the list of rule template names to exclude when running the script, you can pass the -excludeRuleTemplates parameter as an array of strings. This ensures the script receives the array of rule template names to exclude. Here’s how you can do it:
.EXAMPLE-4
.\Set-AnalyticsRules.ps1 `
-subscriptionId "xxxxxxxx-aaaa-bbbb-cccc-zzzzzzzzzzzz" `
-resourceGroupName "RG-Name" `
-workspaceName "Log-Analytics-Name" `
-solutionName "Azure Activity" `
-excludeRuleTemplates @("New CloudShell User", "Creation of expensive computes in Azure") `
-enableRules Yes -Verbose
To exclude the Preview and Deprecated Rule Templates when running the script, you can pass the -excludePreviewDeprecated parameter as a switch [Yes/No]. Here’s how you can do it:
.EXAMPLE-5
.\Set-AnalyticsRules.ps1 `
-subscriptionId "xxxxxxxx-aaaa-bbbb-cccc-zzzzzzzzzzzz" `
-resourceGroupName "RG-Name" `
-workspaceName "Log-Analytics-Name" `
-solutionName "Microsoft Entra ID" `
-excludePreviewDeprecated Yes `
-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 content solution name. Please note that you need to enter and pass the name of the solution(s) [Content title] as shown in the Content hub blade in the figure below (E.g. Microsoft Entra ID, Azure SQL Database, DNS Essentials, Windows Security Events, Azure Activity, SAP applications, etc.) – Case-insensitive.

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
Updated – 13/08/2025 – The tool below has been updated to fix the incident and grouping configuration for the analytic rule template to validate the time span value in ISO 8601 format.
Updated – 06/05/2025 – The tool below has been updated to include a new option that excludes Preview and Deprecated Rule Templates from deployment and activation.
Updated – 01/05/2025 – The tool below has been updated to include a new option that allows you to exclude specific rule template names from deployment and activation.
Updated – 22/05/2024 – The tool below has been updated to include the MITRE ATT&CK “Sub techniques” for the analytic rule, which requires a preview API version in addition to the “Tactics” and “Techniques“.
Updated – 27/12/2023 – The tool below has been updated to identify all installed solutions. You need to enter and pass the name of the solution(s) [Content title] as shown in the Content hub blade.
Updated – 25/10/2023 – The tool below has been updated to identify all installed solutions, despite the discrepancy between the solution name that you see in the Microsoft Sentinel portal and the API.
Updated – 15/10/2023 – The tool below has been updated to incorporate the recent API changes for Content Hub.
Updated – 28/07/2023 – The tool below has been updated to leverage Content Hub GA changes. The Resource Graph is being deprecated by Microsoft and replaced by the REST API.
The complete script is detailed below to automate the entire process of creating and activating the Analytics Rules content pack:
<#
.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 : 3.1
Date : 24-October-2022
Updated : 13-August-2025
Requires : PowerShell 7.4.x (Core)
Module : Az Module
.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" -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, however, you have the option to enable the rules at creation time by setting the parameter -enableRules [Yes].
You also have the option to exclude specific rule templates by using the -excludeRuleTemplates parameter, and you can specify the names of the templates you want to exclude.
The "Preview" and "Deprecated" rule templates can be also excluded by setting the -excludePreviewDeprecated parameter to [Yes]. This option is set to [Yes] by default.
#>
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 Content Hub Solution Name')]
[string]$solutionName,
[Parameter(Position = 4, Mandatory = $false, HelpMessage = 'Exclude Rule Templates Names i.e: @("ABC","DEF")')]
[ValidateNotNullOrEmpty()]
[array]$excludeRuleTemplates,
[Parameter(Position = 5, Mandatory = $false, HelpMessage = 'Exclude [Preview] and [Deprecated] Rule Templates [Yes/No]')]
[ValidateNotNullOrEmpty()]
[ValidateSet("Yes", "No")]
[String]$excludePreviewDeprecated = 'Yes',
[Parameter(Position = 6, Mandatory = $false, HelpMessage = 'Enable Rules at Creation Time [Yes/No]')]
[ValidateNotNullOrEmpty()]
[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 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
}
# Define the Preview API Version to use for Microsoft Sentinel
# The Preview API Version is needed to include the MITRE ATT&CK "Sub techniques"
$apiVersion = "?api-version=2025-01-01-preview"
# Create the authentication access token
Write-Verbose "Creating authentication access token..."
$context = Get-AzContext
if (-not $context) {
throw "No Azure context found. Please re-authenticate."
}
$tokenRequest = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account, $context.Environment, $context.Tenant.Id, $null, "Never", $null, "https://management.azure.com/")
if (-not $tokenRequest) {
throw "Failed to obtain access token. Please check your authentication."
}
$AzureAccessToken = $tokenRequest.AccessToken
$authHeader = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$authHeader.Add("Content-Type", "application/json")
$authHeader.Add("Authorization", "Bearer $AzureAccessToken")
# Get Content Product Packages
$contentURI = "https://management.azure.com/subscriptions/$subscriptionid/resourceGroups/$resourceGroupName/providers/Microsoft.OperationalInsights/workspaces/$workspaceName/providers/Microsoft.SecurityInsights/contentProductPackages$($apiVersion)"
$contentResponse = (Invoke-RestMethod $contentURI -Method 'GET' -Headers $authHeader).value
$solutions = $contentResponse | Where-Object { $null -ne $_.properties.version }
$solution = ($solutions | Where-Object { $_.properties.displayName -eq "$solutionName" }).properties.contentId
# Get Content Templates
$contentURI = "https://management.azure.com/subscriptions/$subscriptionid/resourceGroups/$resourceGroupName/providers/Microsoft.OperationalInsights/workspaces/$workspaceName/providers/Microsoft.SecurityInsights/contentTemplates$($apiVersion)"
$contentResponse = (Invoke-RestMethod $contentURI -Method 'GET' -Headers $authHeader).value
try {
$contentTemplates = $contentResponse | Where-Object { $_.properties.packageId -eq $solution -and $_.properties.contentKind -eq "AnalyticsRule" }
if ($contentTemplates.count -eq 0) {
throw "Solution Name: [$solutionName] cannot be found. Please check the solution name and Install it from the Content Hub blade"
}
}
catch {
Write-Error $_ -ErrorAction Stop
}
if ($excludePreviewDeprecated -eq 'Yes') {
Write-Verbose "Excluding Preview and Deprecated Rule Templates"
$contentTemplatesExcluded = $contentTemplates | Where-Object {
$_.properties.displayName -notmatch '^(Preview|Deprecated)' -and
$_.properties.displayName -notmatch '\[Preview\]' -and
$_.properties.displayName -notmatch '\[Deprecated\]'
}
if ($contentTemplatesExcluded.Count -ne $contentTemplates.Count) {
Write-Verbose "$($contentTemplates.Count - $contentTemplatesExcluded.Count) Analytic Rule(s) were excluded for: [$solutionName]"
$contentTemplates = $contentTemplatesExcluded
}
else {
Write-Verbose "No Preview and Deprecated Analytic Rules were excluded for: [$solutionName]"
}
}
if ($excludeRuleTemplates) {
Write-Verbose "Excluding Rule Templates: $($excludeRuleTemplates -join ', ')"
foreach ($ruleTemplate in $excludeRuleTemplates) {
$contentTemplates = $contentTemplates | Where-Object { $_.properties.displayname -ne "$ruleTemplate" }
}
}
Write-Verbose "$($contentTemplates.count) Analytic Rules found for: [$solutionName]"
foreach ($contentTemplate in $contentTemplates) {
$ruleName = $contentTemplate.name
$ruleTemplateURI = "https://management.azure.com/subscriptions/$subscriptionid/resourceGroups/$resourceGroupName/providers/Microsoft.OperationalInsights/workspaces/$workspaceName/providers/Microsoft.SecurityInsights/contentTemplates/$($ruleName)$($apiVersion)"
$ruleResponse = Invoke-RestMethod $ruleTemplateURI -Method 'GET' -Headers $authHeader -Verbose:$false
$ruleProperties = $ruleResponse.properties.mainTemplate.resources | Where-Object type -eq 'Microsoft.OperationalInsights/workspaces/providers/metadata' | Select-Object properties
$ruleProperties.properties = $ruleProperties.properties | Select-Object * -ExcludeProperty description, parentId
$rule = $ruleResponse.properties.mainTemplate.resources | Where-Object type -eq 'Microsoft.SecurityInsights/AlertRuleTemplates'
$rule.properties | Add-Member -NotePropertyName alertRuleTemplateName -NotePropertyValue $rule.name
$rule.properties | Add-Member -NotePropertyName templateVersion -NotePropertyValue $ruleResponse.properties.version
# Fix Grouping Configuration
if ($rule.properties.PSObject.Properties.Name -contains "incidentConfiguration") {
if ($rule.properties.incidentConfiguration.PSObject.Properties.Name -contains "groupingConfiguration") {
if (-not $rule.properties.incidentConfiguration.groupingConfiguration) {
$rule.properties.incidentConfiguration | Add-Member -NotePropertyName "groupingConfiguration" -NotePropertyValue @{
matchingMethod = "AllEntities"
lookbackDuration = "PT1H"
}
}
else {
# Ensure `matchingMethod` exists
if (-not ($rule.properties.incidentConfiguration.groupingConfiguration.PSObject.Properties.Name -contains "matchingMethod")) {
$rule.properties.incidentConfiguration.groupingConfiguration | Add-Member -NotePropertyName "matchingMethod" -NotePropertyValue "AllEntities"
}
# Ensure `lookbackDuration` is in ISO 8601 format
if ($rule.properties.incidentConfiguration.groupingConfiguration.PSObject.Properties.Name -contains "lookbackDuration") {
$lookbackDuration = $rule.properties.incidentConfiguration.groupingConfiguration.lookbackDuration
if ($lookbackDuration -match "^(\d+)(h|d|m)$") {
$timeValue = $matches[1]
$timeUnit = $matches[2]
switch ($timeUnit) {
"h" { $isoDuration = "PT${timeValue}H" }
"d" { $isoDuration = "P${timeValue}D" }
"m" { $isoDuration = "PT${timeValue}M" }
}
$rule.properties.incidentConfiguration.groupingConfiguration.lookbackDuration = $isoDuration
}
}
}
}
}
If ($enableRules -eq "Yes") {
$rule.properties.enabled = $true
}
$rulePayload = $rule | ConvertTo-Json -EnumsAsStrings -Depth 50
$ruleURI = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.OperationalInsights/workspaces/$workspaceName/providers/Microsoft.SecurityInsights/alertRules/$($rule.name)$($apiVersion)"
try {
$ruleResult = Invoke-AzRestMethod -Method PUT -path $ruleURI -Payload $rulePayload -Verbose:$false
If (!($ruleResult.StatusCode -in 200, 201)) {
Write-Host $ruleResult.StatusCode
Write-Host $ruleResult.Content
throw "Error when enabling Analytics rule: $($rule.properties.displayName)"
}
If ($enableRules -eq "Yes") {
Write-Verbose "Creating and Enabling Analytic rule: $($rule.properties.displayName)"
}
Else {
Write-Verbose "Creating Analytic rule: $($rule.properties.displayName)"
}
}
catch {
Write-Error $_ -ErrorAction Continue
}
If ($ruleResult.StatusCode -in 200, 201) {
$ruleResult = $ruleResult.Content | ConvertFrom-Json
$ruleProperties.properties | Add-Member -NotePropertyName parentId -NotePropertyValue $ruleResult.id
$metadataURI = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.OperationalInsights/workspaces/$workspaceName/providers/Microsoft.SecurityInsights/metadata/analyticsrule-$($rule.name)$($apiVersion)"
$metadataPayload = $ruleProperties | ConvertTo-Json -EnumsAsStrings -Depth 50
try {
$resultMetadata = Invoke-AzRestMethod -Method PUT -path $metadataURI -Payload $metadataPayload -Verbose:$false
if (!($resultMetadata.StatusCode -in 200, 201)) {
Write-Host $resultMetadata.StatusCode
Write-Host $resultMetadata.Content
throw "Error when updating Metadata for Analytic rule: $($rule.properties.displayName)"
}
Write-Verbose "Updating Metadata for Analytic 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-
Hi,
I am ending up in an internal loop with the script constantly installing the Az.accounts and Az.ResourceGraph modules and never proceeding further.
Please advise.
Hello Alex, thanks for the comment!
I recommend removing the Az.accounts and Az.ResourceGraph modules on your machine first and then run the script again.
Run the following command to uninstall the modules:
Hope it helps!
Hello, I am looking for a script to install and activate Sentinel. Here are the solutions I need:
– Azure Active Directory
– Office 365
– Microsoft Defender for Cloud
– Microsoft Defender for Cloud Apps
– Microsoft Defender for Endpoint
– Microsoft Defender for Identity
– Microsoft Defender for Office 365
– Microsoft 365 Defender
Can you help me?
Hello De Poorter, thanks for the comment!
Please find below the updated script to import the Analytics Rules in question.
Assuming that you have imported first the solution(s) in question from Content Hub.
Please note that not all solutions have built-in Analytics Rules, thus I have added the solutions that do have built-in Analytics Rules.
The solution names are case-sensitive.
Please make sure to copy the remaining script from the $rgQuery variable till the end and put it inside: foreach ($solutionName in $solutionNames) { … }.
Hope it helps!
Hello Charbel,
If I understand correctly the source name should be preserved once the rules are created? The problem that I’m having is that if I for example deploy “Microsoft 365” rules the source name is always “Gallery Content”.
If I deploy a single rule manually via GUI the source name is correctly shown as “Microsoft 365” in the active rule tab including the “IN USE” tag in rule templates. Any ideas? Thank you!
Hello Matej, thanks for the comment!
Once you activate and create Rules from the “Rule Templates” Tab, you will see either source name set as “Repositories” or “Gallery Content” in the “Active Rules” Tab, and there is also a third option called “Custom Content” for the custom rules that you create.
I have updated the article to include both Options (Solutions that you imported from Content Hub and the default built-in Analytics Rules in the Gallery Content).
Please check this section and let me know if it works for you.
Thanks!
Works like a charm! This is exactly what I was trying to do. Thank you, you are awesome.
Thank you, Matej for the confirmation! I am happy to hear that.
Hello Charbel,
I have installed the Azure Active Directory content and am running the script from PowerShell as administrator while authenticating with an account which has owner rights on the subscription and resource group. Still however, I receive the Resource Graph query error. Do you have an idea what I am missing?
Thank you
Hello KB, thanks for the comment and for reporting this!
Yes, I faced the same error, this is because Microsoft just announced Content Hub general availability (GA) and Out-of-the-box (OOTB) Content Centralization.
For this to work, please go to your Content Hub and then Delete Azure Active Directory solution all together.
Wait for few minutes… and then install the latest Azure Active Directory version 2.0.13 from Content Hub blade again.
I just tried it and I was able to activate all 59 Analytics Rule Templates for Azure Active Directory.
Hope it helps!
Hi,
Thank you for creating the blog. I was trying to run the script after installing the Azure Active Directory solution but I have been greeted with the same error message as some of the others: “VERBOSE: Sent top=100 skip=0 skipToken=
VERBOSE: Received results: 0
Exception: Resource Graph query error”
I have checked my permissions and I have Owner and Global admin on the subscription in which the sentinel and the LA workspace resides which is inherited.
I have tried uninstalling and installing the modules.
I have tried reinstalling the solution on the content hub as you suggested.
Could you please help me with what the issue could be?
Hello Marcell, thanks for the comment and feedback!
As I mentioned in one of my previous comment, please go to your Content Hub and then “Delete” Azure Active Directory solution all together, and then “wait for few minutes” after the deletion.
Then install the latest Azure Active Directory version from Content Hub blade again, and then “wait for few minutes” after the installation.
Last, try to run the script again and activate the Analytics Rule Templates for Azure Active Directory solution.
Hope it helps!
Hi,
Thank you for the quick response. I have taken the steps you have recommended, and it has resulted in the same output.
I have used the following query in the relevant subscription using Azure Resource Graph Explorer to investigate why the Received results are 0 when running the script.
resources
| where type =~ ‘Microsoft.Resources/templateSpecs/versions’
| where tags[‘hidden-sentinelContentType’] =~ ‘AnalyticsRule’
To my surprise, the query has not returned any results.
When I navigate to the Analytics > Rule templates > sourcename: Azure Active Directory – I can see all 59 of the Analytic rules that I would like to deploy with the script.
Do you have any advice for me?
Hi Charbel, thanks for your work.
I tried your script but i got the same error as above “Resource Graph query error”.
I tried what you said with uninstall / reinstall the content but same result.
So i looked inside the script to understand what is going on, and i saw that on a tenant i got these type of resource :
(Search-AzGraph -Subscription “xxxxxxx” -Query “resources”).type
microsoft.storage/storageaccounts
microsoft.insights/workbooks
microsoft.logic/workflows
microsoft.managedidentity/userassignedidentities
microsoft.operationalinsights/workspaces
microsoft.operationsmanagement/solutions
microsoft.web/connections
microsoft.web/connections
microsoft.web/connections
And no ‘Microsoft.Resources/templateSpecs/versions’ that we are looking for.
The strange part is that on GUI in sentinel instance, we have the AAD connector setup in content hub, with all analytics rules template.
On an other tenant, with same deployment type I got the resources that we are looking for and it’s working as intend…
Do you have an idea?
Hello Marcell, thanks for confirming!
After deep investigation, I checked with Microsoft, unfortunately, the Resource Graph is being deprecated.
If you want to see the rules that were created, you need to use the REST API.
I’ll update the article in the next few days and switch over to the new method.
Hello Ted, thanks for reporting this!
After deep investigation, I checked with Microsoft, unfortunately, the Resource Graph is being deprecated for Sentinel.
If you want to see the rules that were created, you need to use the REST API.
I’ll update the article in the next few days and switch over to the new method.
Hello everyone, please note that the tool has been updated to take into account the new changes that has been implemented by Microsoft.
The Resource Graph for Microsoft Sentinel is being deprecated and replaced by the REST API.
The updated tool is working beautifully. Enjoy :)
Everything works great if I just configure the rules but getting this error when trying to enable the rule –
{“error”:{“code”:”BadRequest”,”message”:”Message: {\”error\”:{\”message\”:\”The request had some invalid properties\”,\”code\”:\”BadArgumentError\”,\”correlationId\”:\”id\”,\”innererror\”:{\”code\”:\”SemanticError\”,\”message\”:\”A semantic error occurred.\”,\”innererror\”:{\”code\”:\”SEM0104\”,\”message\”:\”Operator source expression should be table or column\”}}}};”}}
Command is:
.\Set-AnalyticRules.ps1 -subscriptionId subid -resourceGroupName test-sentinel-rg -workspaceName sentinel-all-in-one -solutionName "CiscoUmbrella" -enableRules Yes -VerboseHello Nick, thanks for the comment and for sharing your feedback!
Yes, I am seeing the same error message on my side, this is because the Cisco Umbrella table is not yet created in Log Analytics workspace.
I am able to create the 10 Analytic Rules for CiscoUmbrella solution, but I cannot enable them because the table is not found.
Please ingest and configure the connector Cisco Umbrella (using Azure Function) first, and then try to run the same command with “
-enableRules Yes”.If you try to enable any of the Analytic Rules manually, you will see the following error message: [Operator source expression should be table or column].
Hope it helps!
Hi there,
Great article by the way but has something recently changed? I’ve used this for a while now but I’ve come to run it today and I’m getting
Solution Name: [Azure Active Directory] cannot be found
I’ve dug a bit deeper and i’m called the API line by line. When I return $solution.Properties these are the only properties returned. In the script i can see you’re looking for properties.mainTemplate.resources.properties.source.name but this doesn’t exists.
packageKind : Solution
packageId : azuresentinel.azure-sentinel-solution-azureactivedirectory
packageVersion : 2.1.2
contentSchemaVersion : 3.0.0
contentProductId : azuresentinel.azure-sentinel-solution-azureactived-ar-tqnkdvnruxnyc
contentId : 500c103a-0319-4d56-8e99-3cec8d860757
displayName : Sign-ins from IPs that attempt sign-ins to disabled accounts
contentKind : AnalyticsRule
version : 2.1.2
I thought about removing the condition and just look for all analytic rules but when trying to create the rule i get the error “specify Required property ‘queryFrequency”. I cant see any reference to this in the script so I’ve no idea where i can find this.
This is two on two different Sentinel instances.
Any ideas?
Thanks in advance.