You dont have javascript enabled! Please enable it!

Automate Microsoft Sentinel Content Hub Updates

10 Min. Read

Microsoft Sentinel comes with Content Hub that you can use out-of-the-box to get content value and get started on Microsoft Sentinel quickly. 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. Updating Content Hub solutions regularly is a tedious job especially if you have a large number of solutions installed.

In this article, we will show you how to automate Microsoft Sentinel Content Hub updates at scale using PowerShell and REST API, this is very useful if you have many solutions installed and you want to automate the update process, saving you time instead of regularly checking for new updated versions.

Microsoft Sentinel Content Hub Updates

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.

Content Hub is designed to provide a consistent and scenario-driven approach for onboarding out-of-the-box (OOTB) content as needed. This is accomplished by organizing solutions into packages that comprise data connectors, analytics rules, hunting queries, parsers, playbooks, workbooks, and watchlists. These solutions assist enterprise security operations (SecOps) teams in managing their business from data ingestion to security monitoring, issue detection, threat hunting, and breach response, all in a scenario-driven mode. With filters to easily discover content for domain categories, content types, support, and more, these solutions enable SecOps teams to handle their business operations more efficiently.

Microsoft Sentinel | Content Hub
Microsoft Sentinel | Content Hub

Standalone content and solutions in Content Hub can be installed individually or all together in bulk. You can also select multiple solutions and standalone content to install and update them all at once.

Microsoft Sentinel | Install and update content hub solutions
Microsoft Sentinel | Install and update content hub solutions

Those contents get regularly updated by Microsoft and technology partners. The question that often comes up: Is there a way to automatically update solutions in Content Hub, so I don’t have to set a reminder every month to go through and check to see which one has a new updated version?

As you probably know, this is a tedious operation to do manually in the Azure portal. At the time of this writing, there is no out-of-the-box native component that alleviates this manual process.

Related: Check How To Enable Microsoft Sentinel Analytics Rules at Scale.

Let’s see how to automate this process and update Microsoft Sentinel Content Hub solutions 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.

To install 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 the Az PowerShell modules version installed
Get-Module -Name Az.Accounts -ListAvailable | Select Name, Version

5) You need to have one or more solutions installed from Content Hub first before you run the script described below.

6) Last, make sure you have the Microsoft Sentinel Contributor role permission which is required to install and manage content from the content hub.

Assuming you have all the prerequisites in place, take the following steps:

Update Microsoft Sentinel Content Hub

This section will describe how to update Microsoft Sentinel Content Hub for the solution(s) that you imported and installed.

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

.\Update-ContentHub -SubscriptionId "xxxxxxxx-aaaa-bbbb-cccc-zzzzzzzzzzzz" `
 -ResourceGroup "RG-Name" -WorkspaceName "Log-Analytics-Name" -Verbose

This example will connect to your Azure account using the subscription ID specified, and then check for the installed solutions in the Content Hub and filter the ones that require an update.

Here is an example of the output once you run this tool:

Update Microsoft Sentinel Content Hub Solutions
Update Microsoft Sentinel Content Hub Solutions

Related: Check How To Delete Microsoft Sentinel Analytics Rule Templates.

PowerShell Code

The complete script is detailed below to automate the entire process of updating the installed Content Hub solutions. You need to run this script on-demand, check the next section to learn how to automate the update process based on a weekly schedule.

<#
.SYNOPSIS
Update Microsoft Sentinel Content Hub Solutions at Scale.

.DESCRIPTION
How to update Microsoft Sentinel Content Hub Solutions at Scale using PowerShell and REST API.

.NOTES
File Name : Update-ContentHub.ps1
Author    : Microsoft MVP/MCT - Charbel Nemnom
Version   : 1.0
Date      : 29-November-2023
Updated   : 01-December-2023
Requires  : PowerShell 6.2 or PowerShell 7.x.x (Core)
Module    : Az Module

.LINK
To provide feedback or for further assistance please visit:
 https://charbelnemnom.com 

.EXAMPLE
.\Update-ContentHub.ps1 -SubscriptionId <SUB-ID> -ResourceGroup <RG-Name> -WorkspaceName <Log-Analytics-Name> -Verbose
This example will connect to your Azure account using the subscription ID specified, and then check for the installed solutions in the Content Hub and filter the ones that require an update.
#>

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    
)

#! 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 
}

#! Get Az Access Token
$token = Get-AzAccessToken #This will default to Azure Resource Manager endpoint
$authHeader = @{
    'Content-Type'  = 'application/json'
    'Authorization' = 'Bearer ' + $token.Token
}

# Define the latest API Version to use for Sentinel
$apiVersion = "?api-version=2023-10-01-preview"

# Get Content Hub Solutions
$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
# Filter Installed Content Hub Solutions which requires an update
$solutions = $contentResponse | Where-Object { $null -ne $_.properties.installedVersion -and $_.properties.installedVersion -lt $_.properties.version }

try {   
    if ($solutions.count -eq 0) {
        throw "All the installed Content Hub solutions are currently up to date. No update is required."
    }
    Write-Verbose "$($solutions.count) Content Hub solutions were found installed and require an update."
}
catch {
    Write-Error $_ -ErrorAction Stop
}

foreach ($solution in $solutions) {
    $contentPackageName = $solution.properties.contentId
    $contentProperties = $solution | Select-Object properties
    $contentPayload = $contentProperties | ConvertTo-Json -Depth 100
    $contentPackageURI = "https://management.azure.com/subscriptions/$subscriptionid/resourceGroups/$resourceGroupName/providers/Microsoft.OperationalInsights/workspaces/$workspaceName/providers/Microsoft.SecurityInsights/contentPackages/$($contentPackageName)$($apiVersion)"
    $contentPackageResponse = Invoke-AzRestMethod $contentPackageURI -Method 'PUT' -Payload $contentPayload -Verbose:$false    
    
    try {        
        if (!($contentPackageResponse.StatusCode -in 200, 201)) {
            Write-Host $contentPackageResponse.StatusCode
            Write-Host $contentPackageResponse.Content
            throw "Error when updating Content Hub Solution [$($solution.properties.displayName)]"
        }
        Write-Verbose "Content Hub Solution [$($solution.properties.displayName)] updated successfully!"
    }
    catch {
        Write-Error $_ -ErrorAction Continue

    }   
}

Before running this tool, we can see that we have 5 Updates available for the installed solutions.

Content Hub | Available Update
Content Hub | Available Update

Once you run this tool, you can refresh the Content Hub blade and check that all the installed solutions are updated to the latest version. In this example, we have 10 solutions installed and updated.

Content Hub | Solutions Updated
Content Hub | Solutions Updated

Automate Microsoft Sentinel Content Hub Updates

The next step is to automate Content Hub updates by using Azure Automation Accounts, Azure Logic Apps, or Azure Functions. In this example, we will look at automating this update process using Automation Accounts.

You might ask why Automation Accounts instead of Azure Logic Apps or Azure Functions? Creating Runbooks as part of process automation is easier to configure and Automation Accounts is cheaper compared to Logic App or Function App.

First, we need to create an Azure automation resource with a Managed Identity. Microsoft recommends using Managed Identities for the Automation accounts instead of using Run As accounts. Managed identity would be more secure and offer ease of use since it doesn’t require any credentials to be stored. Azure Automation support for Managed Identities is now generally available.

Create Automation Account

When you create an Automation Account, it creates a new service principal in Microsoft Entra ID (formerly Azure AD) by default. Next, you must assign the appropriate (Azure RBAC) role to allow access to Microsoft Sentinel for the service principal at the resource group level where Sentinel is deployed.

In this example, we have assigned the Microsoft Sentinel Contributor role to the managed identity at the resource group level. Always keep in mind to use the principle of least privilege (PoLP) when assigning permissions.

Add role assignment to Automation Account Managed Identity
Add role assignment to Automation Account Managed Identity

Using a managed identity instead of the Automation Run As account makes management simpler. You don’t have to renew the certificate used by the Automation Run As account. Additionally, you don’t have to specify the Run As connection object in your runbook code. You can access resources using your Automation account’s managed identity from a runbook without creating certificates, connections, Run As accounts, etc.

If you have an existing Automation Account with system-assigned managed identity enabled, then you can skip this step and jump to the “Create PowerShell Runbook” section.

Using a system-assigned managed identity for an Azure Automation account
Using a system-assigned managed identity for an Azure Automation account

Open the Azure portal, and click All services found in the upper left-hand corner. In the list of resources, type Automation. As you begin typing, the list filters based on your input. Select Automation Accounts.

Click +Add. Enter the automation account name, and choose the right subscription, resource group, and location. By default, a system-assigned managed identity is selected.

Create an Automation Account with Managed Identity
Create an Automation Account with Managed Identity

Then select Review + Create and click Create.

Az Modules

In your list of Automation Accounts, select the account you created in the previous step. Then from your Automation account, select Modules under Shared Resources.

The good news is that starting in September 2021, automation accounts will now have the Az modules installed by default. You don’t need to import the modules from the gallery as we used to do in the past. Please note that you can also update the modules to the latest Az version from the modules blade as shown in the figure below.

As a side note, Azure Automation announced the General Availability of PowerShell 7.2 Runbooks. PowerShell 7.1 is no longer supported by the parent product PowerShell. It is strongly recommended to create PowerShell 7.2 Runbooks for long-term support.

Automation Account Update Az Module
Automation Account Update Az Module

The most common PowerShell modules are provided by default in each Automation account. See the default modules imported on this page. As the Azure team updates the Azure modules regularly, changes can occur with the included cmdlets.

Create PowerShell Runbook

In this step, you create a PowerShell Runbook to automatically update the Content Hub solutions. You can directly edit the code of the Runbook using the text editor in the Azure portal. Or, you can also use any offline text editor such as Visual Studio Code, and import the Runbook into Azure Automation.

From your automation account, select Runbooks under Process Automation. Click the ‘+ Create a runbook‘ button to open the Create a runbook blade as shown in the figure below.

Please make sure to select the right runtime PowerShell version. In this example, the PowerShell modules (Az.Accounts) targeting the 7.2 runtime version will be used.

Create a PowerShell runbook in Automation Account
Create a PowerShell runbook in the Automation Account

Edit the Runbook

Once you have the Runbook created, you need to edit the Runbook and add the script below. As mentioned earlier, we will create a Runbook to connect to your Azure account using the subscription ID specified, and then check for the installed solutions in the Content Hub that require an update, and then install the latest version.

The automation runbook is as follows:

<#
.SYNOPSIS
Update Microsoft Sentinel Content Hub Solutions at Scale.

.DESCRIPTION
How to update Microsoft Sentinel Content Hub Solutions at Scale using PowerShell and REST API.

.NOTES
File Name : Update-ContentHub.ps1
Author    : Microsoft MVP/MCT - Charbel Nemnom
Version   : 1.0
Date      : 29-November-2023
Updated   : 01-December-2023
Requires  : PowerShell 5.1 or PowerShell 7.3.x (Core)
Module    : Az Module

.LINK
To provide feedback or for further assistance please visit:
 https://charbelnemnom.com
#>

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    
)

# Ensures you do not inherit an AzContext in your runbook 
Disable-AzContextAutosave -Scope Process 

# Connect to Azure with system-assigned managed identity (automation account) 
Connect-AzAccount -Identity 

# Set Azure Subscription context
Set-AzContext -Subscription $subscriptionId

#! Get Az Access Token
$token = Get-AzAccessToken #This will default to Azure Resource Manager endpoint
$authHeader = @{
    'Content-Type'  = 'application/json'
    'Authorization' = 'Bearer ' + $token.Token
}

# Define the latest API Version to use for Sentinel
$apiVersion = "?api-version=2023-10-01-preview"

# Get Content Hub Solutions
$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
# Filter Installed Content Hub Solutions which requires update
$solutions = $contentResponse | Where-Object { $null -ne $_.properties.installedVersion -and $_.properties.installedVersion -lt $_.properties.version }
  
if ($solutions.count -eq 0) {
    Write-Output "All the installed Content Hub solutions are currently up to date. No update is required."
}
Else {
    Write-Output "$($solutions.count) Content Hub solutions were found installed and require an update."
    
    foreach ($solution in $solutions) {
        $contentPackageName = $solution.properties.contentId
        $contentProperties = $solution | Select-Object properties
        $contentPayload = $contentProperties | ConvertTo-Json -Depth 100
        $contentPackageURI = "https://management.azure.com/subscriptions/$subscriptionid/resourceGroups/$resourceGroupName/providers/Microsoft.OperationalInsights/workspaces/$workspaceName/providers/Microsoft.SecurityInsights/contentPackages/$($contentPackageName)$($apiVersion)"
        $contentPackageResponse = Invoke-AzRestMethod $contentPackageURI -Method 'PUT' -Payload $contentPayload -Verbose:$false    
    
        try {        
            if (!($contentPackageResponse.StatusCode -in 200, 201)) {
                Write-Host $contentPackageResponse.StatusCode
                Write-Host $contentPackageResponse.Content
                throw "Error when updating Content Hub Solution [$($solution.properties.displayName)]"
            }
            Write-Output "Content Hub Solution [$($solution.properties.displayName)] updated successfully!"
        }
        catch {
            Write-Error $_ -ErrorAction Continue

        }
        Write-Output ("")
    }   
}

Save the script in the CMDLETS pane as shown in the figure below.

Edit PowerShell Runbook in Azure Automation
Edit PowerShell Runbook in Azure Automation

Then test the runbook using the “Test pane” and fill in all the required parameters to verify it’s working as intended before you publish it.

On the Test page, you need to supply the following 3 parameters manually and then click the Start button to test the automation script.

  1. SUBSCRIPTIONID
  2. RESOURCEGROUPNAME
  3. WORKSPACENAME
Test Automate Microsoft Sentinel Content Hub Updates
Test Automate Microsoft Sentinel Content Hub Updates

Once the test is completed successfully, you need to publish the Runbook by clicking the Publish button. This is a very important step.

Schedule the Runbook

In the final step, you need to schedule the Runbook to run based on the desired time that you want to check for content hub updates.

Within the same Runbook that you created in the previous step, select Schedules and then click “+ Add Schedule“.

So, if you need to schedule the Runbook to run every week, then you need to create the following schedule with Recur every 1 Week, pick the desired day of the week, Set the expiration to No, and then click “Create“. The minimum you can run the Runbook every 1 hour and you can also run it on-demand if you wish to do so.

Add a schedule for Runbook
Add a schedule for Runbook

While scheduling the Runbook, you need to enter the required parameters for the PowerShell script to run successfully. In this scenario, you need to specify the following 3 parameters:

  • Azure Subscription ID: Where the Sentinel instance is provisioned.
  • Resource Group: Where Microsoft Sentinel is deployed.
  • Workspace Name: The Log Analytics Workspace name.

The automation script takes those parameters as input as shown in the figure below.

Add required parameters
Add required parameters

Once done, click OK twice.

Last, you can test and monitor the Runbook from the “Jobs” page of Runbooks under the Resources section.

Runbook Jobs
Runbook Jobs

That’s it there you have it. Happy Automating and Updating Microsoft Sentinel Content Hub Solutions!

If you have any feedback or changes that everyone should receive, please feel free to leave a comment below.

In Summary

This article showed you how to update Microsoft Sentinel Content Hub at scale using PowerShell and REST API, this is very useful if you have many solutions installed as part of Content Hub and you want to automate the update regularly by using Automation Accounts, Azure Logic Apps, or Azure Functions.

The Microsoft Sentinel Content Hub is a centralized platform where you can explore and manage ready-made content. It offers a range of pre-packaged solutions for specific industries and domains. Additionally, you can access a wide variety of individual contributions available on our GitHub repository and feature blades. 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-

Photo of author
About the Author
Charbel Nemnom
Charbel Nemnom is a Senior Cloud Architect with 20+ years of IT experience. As a Swiss Certified ICT Security Expert, CCSP, CISM, MVP, and MCT, he excels in optimizing mission-critical enterprise systems. His extensive practical knowledge spans complex system design, network architecture, business continuity, and cloud security, establishing him as an authoritative and trustworthy expert in the field. Charbel frequently writes about Cloud, Cybersecurity, and IT Certifications.
Previous

AWS Cost Categories: Explained in Plain English

Mastering Google Cloud Logging | Expert Guide

Next

5 thoughts on “Automate Microsoft Sentinel Content Hub Updates”

Leave a comment...

  1. Thank for the great article!

    Is it possible to automate updates from another tenant using automation account? Or should this be done with logic apps using API queries? I would prefer to centralize all automation related actions from my main tenant.

  2. Hello John, thanks for the comment and feedback!
    To answer your question, yes, it would be possible to automate updates from another tenant using Automation Account instead of using Logic Apps.
    For that to work, you need to create an Application Registration (Service Principal) in “Tenant2”; store the Application (Client) ID and Secret Value in a Key Vault in the main Tenant; then have the runbook retrieve the password and use it to authenticate when needed for actions in “Tenant2”.
    You could also store the Application (Client) ID and Secret Value in the Automation Account under Shared Resources > Credentials.
    The following example shows how to use a PowerShell credential in a Runbook. It retrieves the credential and assigns its user name (Application ID) and password to variables.

    $tenant2Credential = Get-AutomationPSCredential -Name 'Tenant2Credential'
    $applicationId = $tenant2Credential.UserName
    $securePassword = $tenant2Credential.Password
    $password = $tenant2Credential.GetNetworkCredential().Password
    $Credential = New-Object System.Management.Automation.PSCredential ($applicationId,$securePassword)

    Then you can authenticate to Tenant2 by using the “Connect-AzAccount -ServicePrincipal -TenantId Tenant2ID -Credential $Credential” command to connect to “Tenant2” from your automation account in the main Tenant.
    Last, make sure to assign the Service Principal in “Tenant2”, the appropriate permissions on the Resource Group where Microsoft Sentinel is deployed, so you can automate the updates for Content Hub.
    I would prefer to create a custom role with the least privilege in “Tenant2”, to automate the updates in Content Hub instead of using the built-in “Microsoft Sentinel Contributor” role.
    Hope it helps!

  3. This seems to have stopped working for me recently. I did some analysis and noticed that the script compares installed version and version.
    I was looking at the output and it was always none need updated. When I manually ran the command to pull back the results from the API, I noticed that installed version doesn’t seem to exist anymore?

  4. Hello Colin, thanks for the comment and for reporting this issue!
    Yes, this is correct. The installed version is missing from the output now.
    I am checking with Microsoft and I will update the script as soon as this bug is identified.
    It’s clearly noted in the official documentation page that the installed version is part of the properties of the response.
    Stay Tuned!

Let me know what you think, or ask a question...

error: Alert: The content of this website is copyrighted from being plagiarized! You can copy from the 'Code Blocks' in 'Black' by selecting the Code. Thank You!