Introduction
In this post, we will get ready to use the Azure Sentinel REST APIs. We will discuss getting PowerShell setup, what needs to be done before you can call the REST APIs and then we will make a sample call.
First and foremost, we will be using the new PowerShell core. It is the new cross-platform PowerShell that was built using .Net core and can run on Windows, Linux and MacOS. Disclaimer: I have only tried the code I am going to show you on Windows. The current release is V6 (although V7 is in preview and should be GA very soon). It also makes working with REST calls to Azure much easier. There is no need to setup an application in Azure AD anymore. You can just connect to your environment via the login window.
1) Install PowerShell
Go to https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell?view=powershell-6 to go to the home page for the new PowerShell. There is a drop down in the upper left hand corner where you can switch to V7 if you so desire. Follow the link to install the version for your operating system.
2) Install Azure PowerShell module
Once PowerShell is installed, you need to install the Azure PowerShell module. This is easy and can be done directly from PowerShell. Go to https://docs.microsoft.com/en-us/powershell/azure/install-az-ps?view=azps-3.2.0 for more instructions on how to do that.
3) Connect to Azure
Once you are all setup and ready to go, you need to connect to your Azure environment. Use the command
Connect-AzAccount
to do that. If you have used this with the previous version of PowerShell, you will notice that you are not prompted to login. Instead there is a message:
WARNING: To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code XXXXXXXX to authenticate.
Where the actual code will be different. When you go to the link you will be prompted to enter the code as shown below.
Enter the code from the message and click Next. You will then be prompted to login as you normally do. Once you have successfully logged in, you will be presented with the message shown below.
You can now close this window and you will notice your PowerShell window shows your login information.
4) Setup needed Variables
$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 }
Now that you are logged in, there are some variables that need to be set. The final outcome here is to generate a header that can be passed in to all the REST calls you will be making. Run the following commands
Note that if you try to run this in the older version of PowerShell you will get an error when using the AcquireAccessToken command
5) Define the URL
Now you are ready to define the URL. The first thing we are going to do is to return all the Incidents you have. If you look at the API specification document, SecurityInsights.json, that you downloaded from the previous post, you will find this entry under the “paths” section:
"/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{operationalInsightsResourceProvider}/workspaces/{workspaceName}/providers/Microsoft.SecurityInsights/cases"
This is the path that you need to call to get a listing of all the Incidents you have. If you are not aware, Incidents in Azure Sentinel used to be called cases hence the reason “cases” is used in the path.
The path you need to call is:
https://management.azure.com
so the (almost) entire path (without making the needed substitutions) is:
https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{operationalInsightsResourceProvider}/workspaces/{workspaceName}/providers/Microsoft.SecurityInsights/cases
There is one more part of the URL that needs to be added. The REST API needs to know what version to use. For all of the calls, unless told otherwise, use “2019-01-01-preview” so really the full URL will be
https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{operationalInsightsResourceProvider}/workspaces/{workspaceName}/providers/Microsoft.SecurityInsights/cases?api-version=2019-01-01-preview
So, now we are closer. We need to make the substitutions for those words in the braces, like {subscriptionId}. Most should be easy enough to figure out: The subscription GUID for subscriptionId, the name of the resource group where you Log Analytics workspace resides for the resourceGroupName, and the name of the Log Analytics workspace for the workspaceName.
That leaves the “operationalInsightsResourceProvider”. What is this? Once again, we are dealing with Microsoft legacy names. Log Analytics used to be called Operational Insights so that is just the name of the Log Analytics provider which, in all cases unless told otherwise, will be “Microsoft.OperationalInsights”
With all the, fake, substitutions added, a full URL would look like:
https://management.azure.com/subscriptions/ffffffff-ffff-ffff-ffff-fffffffffff/resourceGroups/sentinel-resourcegroup/providers/Microsoft.OperationalInsights/workspaces/sentinel-workspace/providers/Microsoft.SecurityInsights/cases?api-version=2019-01-01-preview
You will most likely want to set this to a PowerShell variable to make it easier to call later.
6) Call the REST API
Now you are ready to make the REST API call. PowerShell provides the
Invoke-RestMethod
command to make the actual call. You will need to provide the Method, Uri, and Header parameters. Assuming you set the URL from Step 5 to the PowerShell variable called “$url” the call would be:
Invoke-RestMethod -Method "Get" -Uri $url -Headers $authHeader
When you run this command you will see that you just get one really long string returned. While this may be useful in code, in actual practice it makes it a bit hard to view. There are two different options. The first involves converting the text to JSON to make it easier to read. This can be done by running:
ConvertTo-Json(Invoke-RestMethod -Method "Get" -Uri $url -Headers $authHeader )
or you can look at everything as PowerShell objects by running:
(Invoke-RestMethod -Method "Get" -Uri $url2 -Headers $authHeader).value
In either case you will want to set the output to a variable. Something interesting to consider. If you run the command to convert to to JSON at the very end id a “nextLink” entry. This will give you the URL you need to run to get the next set of results. Running the command to get the PowerShell object does not have this. Not sure why.
Conclusion
Now you know how to make the call to get a listing of all the Incidents in your environment…or at least a number of them and then the URL to get the next batch. Next time we will look at what can you do with these Incidents.
I’m getting “Exception calling “AcquireAccessToken” with “1” argument(s): “‘authority’ Uri should have at least one segment in the path (i.e. https:////…)” even with PowerShell 6.2.4
Are all the other variables providing proper results ($context, $profile, $profileClient)? I seem to recall getting that error when I forgot to login one time.
I have result in $profile. The next line New-Object -TypeName Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient -ArgumentList ($profile) returns nothing.
Found this from MS: Try running Clear-AzContext then connecting to Azure again. If you have more than one Context in cache it will throw this error.
Another question: Do you have multiple subscriptions? It may be that the default subscription is one you do not have rights to connect to using PowerShell
you can access nextLink but simply:
$response = Invoke-Rest….
$response.nextLink
Hey Gary, Firstly thanks for putting together such a rich collection of articles, it is a really helpful resource to get to grips with this. I came to your site in the hope of exporting Analytic Rules which I found in another one of your articles. I am new to Azure and it’s API capabilities so I thought I would start at the beginning, and have tried to run through this guide.
I am struggling to get it to work and was wondering if you had seen this before or have any thoughts on where to look next:
| $token = $profileClient.AcquireAccessToken($context.Subscription.Tena … | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Exception calling “AcquireAccessToken” with “1”
| argument(s): “Invalid tenant id provided. You can locate
| your tenant id by following the instructions listed
| here:
| https://docs.microsoft.com/partner-center/find-ids-and-domain-names”
After connecting I have run the Get-AzTenant command and can see the two tenant ID’s displayed correctly. I have tried to research the error, but I don’t seem to be able to find the cause. Any help would be greatly appreciated. Thanks
Not sure why you would see two tenants but get the error message. Try to set your subscription using “Select-AzSubscription -SubscriptionId” before getting the context to see if that fixes it.