Automatically apply updates to Analytic rules that have “Update Available”

Introduction

If you do not keep up to date with the analytic rules, you may find yourself in the scenario where there are a lot of rules that have updates that can be applied. If you follow the process, you should look at all the changes that will be applied and then update the rule. This can be a time consuming process.

IF you know that you have not made any changes to the analytic rule when it was created from the template, then it would be great to just tell Microsoft Sentinel to go ahead and update the rules. Unfortunately, this is not possible.

The PowerShell script I wrote will do this for you. But let me re-iterate

This will update ALL the rules. You will not see what the changes are that will be applied! You cannot just update a single rule. It will update ALL the rules.

The code

This code itself is pretty simple.

  1. Load all the analytic rules
  2. Load all the rule templates.
  3. Check to see if it was created from a template and if so, get the rule’s version number
  4. Compare the rule’s version number to the template’s version number
  5. If they match, do nothing.
  6. If they do not match:
    1. Get all the information from the template
    2. Update the rule with this information, including the new version number.

If you have read my blog posts, steps 1 and 2 are easy enough to do. You need to make sure that when you call the APIs you use at least API version “2021-10-01-preview” to get the version information.

For step 3, it is just a simple check to see if the proper field has a value

#Does this rule have a template version
if ($null -ne $rule.properties.templateVersion) {

Step 4 just entails getting the proper information and performing the check

$templateID = $rule.properties.alertRuleTemplateName
$template = $ruleTemplates | Where-Object { $_.name -eq $templateID }
$templateVersion = $template.properties.version
 #We are comparing using not equal for the comparison since the only way the rule version number will change is during an update, unless it is updated
#via the REST API in which case, buyer beware!
if ($rule.properties.templateVersion -ne $templateVersion) {

Steps 5 and 6 will have the script create the new body that will pass into the REST API to update the rule, if the version numbers don’t match, of course.

$body = @{
    "kind"       = "Scheduled"
    "properties" = @{
        "displayName"           = $template.properties.displayName
        "description"           = $template.properties.description
        "severity"              = $template.properties.severity
        "tactics"               = $template.properties.tactics
        "techniques"            = $template.properties.techniques
        "query"                 = $template.properties.query
        "queryFrequency"        = $template.properties.queryFrequency
        "queryPeriod"           = $template.properties.queryPeriod
        "triggerOperator"       = $template.properties.triggerOperator
        "triggerThreshold"      = $template.properties.triggerThreshold
        "entityMappings"        = $template.properties.entityMappings
        "fieldMappings"         = $template.properties.fieldMappings
        "enabled"               = $rule.properties.enabled
        "eventGroupingSettings" = $rule.properties.eventGroupingSettings
        "alertRuleTemplateName" = $rule.properties.alertRuleTemplateName
        "suppressionDuration"   = $rule.properties.suppressionDurationclear
        "suppressionEnabled"    = $rule.properties.suppressionEnabled
        "incidentConfiguration" = $rule.properties.incidentConfiguration
        }
    }

Finally, we need to call the REST API to update this rule. To do that we need to get the GUID of the analytic rule so that we update a specific rule, rather than create a new one.

$guid = $rule.name

#Create the URI we need to update the alert.
$uri = "https://management.azure.com/subscriptions/$($subscriptionId)/resourceGroups/$($resourceGroupName)/providers/Microsoft.OperationalInsights/workspaces/$($workspaceName)/providers/Microsoft.SecurityInsights/alertRules/$($guid)?api-version=2021-10-01-preview"
try {
    Write-Host "Attempting to update rule $($displayName)"
    $verdict = Invoke-RestMethod -Uri $uri -Method Put -Headers $authHeader -Body ($body | ConvertTo-Json -EnumsAsStrings -Depth 5)
    Write-Output -ForegroundColor Green "Succeeded"
}
catch {
     #Output any error
     $errorReturn = $_
     Write-Error $errorReturn
}
#This pauses for 5 second so that we don't overload the workspace.
Start-Sleep -Seconds 5

And that is all there is to it! As new features are added to MS Sentinel, this code will need to be updated to make sure the new properties are taking into account.

Summary

This code will automatically update ALL the rules that need to be updated. Let me re-iterate one more time:

This will update ALL the rules. You will not see what the changes are that will be applied! You cannot just update a single rule. It will update ALL the rules.

Leave a Reply

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.