Updating an Incident using REST calls in PowerShell

Introduction

I was recently asked how an Azure Sentinel Playbook could update the owner of an Incident automatically. Well, there are two issues with that:

  1. Only Scheduled rules can trigger Playbooks (at least right now. <hint>, <hint> Microsoft!). You can however run the Playbook from the Incident’s Full Details page using the Alert tab.
  2. The Logic App Azure Sentinel actions allow you to change many fields of an Incident but the Owner is not one of them. I would guess this is because you need to know the User’s GUID although you can get that from the Azure AD action.

In any case, assuming issue #1 is not that big of an issue, you can use the Logic App HTTP action to get the needed information, another action to make the manipulation and the HTTP action to perform the PUT.

I am not going to show how to create this Playbook, instead I will continue down the path of doing everything in PowerShell and then it can be translated into something that a Playbook can use.

You could modify this code to look for all the unassigned Incidents, determine who to assign them to, and then use this code to update the Incidents. Finally, use Azure Automation to run the PowerShell script on a set schedule. It will not be automatic, but if the schedule to run frequently the Incidents will be updated quickly.

Step 1 – Get the Incident

First you will need to load the existing Incident’s information into a variable. You are doing this so that all the existing information will be retained.

Refer back to Your first Azure Sentinel REST API call for information on how to make the REST call to get a listing of all the Incidents. Right now, we only care about the Name field which contains the Incident’s GUID. This will be needed to make the call to get the individual Incident’s information. While you can get the information you need from this call, it is easier to make the call to get the individual Incident’s information since you will need to make that call to update it later.

The format for the URL will be

"https://management.azure.com/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.OperationalInsights/workspaces/<workspaceName>/providers/Microsoft.SecurityInsights/cases/<IncidentName>?api-version=2019-01-01-preview" 

Making the needed substutions for <subscriptionId>, <resourceGroupName>, <workspaceName>, and <IncidentName>

We are going to make the call to that URL and store the data into the $body variable to make it easier to make the update call later.

$body =  (Invoke-RestMethod -Method "Get" -Uri $uri -Headers $authHeader )

If you have read some of my other blog posts about getting the data using the Invoke-RestMethod you may have noticed that we are not taking just the results variable from the call. This is because this call does not return the results variable, everything is in the main body.

Now that you have all the information in the $body variable we need to make the updates. In this case we are going to update the owner field that is part of the properties field and we are going under the assumption that you know the account’s GUID that you will be using.

The owner field is itself made up of three fields; objectId – which is the GUID, email -which is the email, and name – which is the user’s display name. All three will need to be updated in order for the new owner to take affect.

$body.properties.owner.objectId = "<guid>"
$body.properties.owner.email = "gary.bushey@garybushey.com"
$body.properties.owner.name = "Gary Bushey

Now it is just a matter of making the PUT call as we have done in other posts

$result = Invoke-RestMethod -Uri $uri -Method Put -Headers $authHeader -Body ($body | ConvertTo-Json -EnumsAsStrings)

The full code for this example is as follows:

#requires -version 6.2

$context = Get-AzContext
$profile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile
$profileClient = New-Object -TypeName Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient -ArgumentList ($profile)
$token = $profileClient.AcquireAccessToken($context.Subscription.TenantId)
$authHeader = @{
    'Content-Type'  = 'application/json' 
    'Authorization' = 'Bearer ' + $token.AccessToken 
}


$uri = "https://management.azure.com/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.OperationalInsights/workspaces/<workspaceName>/providers/Microsoft.SecurityInsights/cases/<IncidentName>?api-version=2019-01-01-preview" 

$body =  (Invoke-RestMethod -Method "Get" -Uri $uri -Headers $authHeader )

$body.properties.owner.objectId = "<guid>"
$body.properties.owner.email = "gary.bushey@garybushey.com"
$body.properties.owner.name = "Gary Bushey"

try {
    $result = Invoke-RestMethod -Uri $uri -Method Put -Headers $authHeader -Body ($body | ConvertTo-Json -EnumsAsStrings)
    Write-Output "Successfully updated rule: $($DisplayName) with status: $($result.StatusDescription)"
    Write-Output ($body.Properties | Format-List | Format-Table | Out-String)
}
catch {
    $errorReturn = $_
    Write-Error $errorReturn
    #Write-Error "Unable to invoke webrequest with error message: $($errorResult.message)" -ErrorAction Stop
}

Conclusion

As you can see, it is not very hard to update an Incident using PowerShell and REST calls. While this example updated the owner field, you should be able to change the code to update most other fields as well.

Leave a Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

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