Introduction
If you have connected your Microsoft Sentinel instance to your Microsoft Defender instance (and if not, why not?), you know that the same incidents and alerts will show up in both instances. You can use either the Microsoft Sentinel REST API or the MS Graph to get the data. So, which one should it be?
Yes, I know that Microsoft Defender has its own APIs but if you look at the page for it, Overview of Microsoft Defender XDR APIs – Microsoft Defender XDR | Microsoft Learn, it keeps pointing to the Graph API so I will not be talking about the Defender APIs.
Setup
What I have done is create an Analytic Rule that just uses a KQL “datatable” to create the data I need as shown below.
let X = datatable(User: string, Date: datetime, Host: string, IPAddress: string) [
"Gary Bushey", datetime(2025-01-11), "Computer1","192.18.0.1",
"Archie Dog", datetime(2025-01-10),"Computer 2", "192.168.0.2"];
X
I’ve selected some MITRE tactics and techniques as well as entities (as shown below) just to see all the information.
Microsoft Sentinel REST APIs
I am not going to go into much detail on this since I have talked about it many times in my other blog posts. One thing I will say is that you would need to make one call to get the incident and another to the alerts.
Making the call to get the incident returns the following in the “properties” field (converted into JSON):
{
"title": "Incident from Archie Dog on multiple endpoints",
"severity": "Medium",
"status": "Active",
"owner": {
"objectId": "50780ddd-8bbd-433e-bffd-d1574a7350eb",
"email": "GaryBushey@GABTest419.onmicrosoft.com",
"assignedTo": "Gary Bushey",
"userPrincipalName": "GaryBushey@GABTest419.onmicrosoft.com",
"ownerType": "User"
},
"labels": [],
"firstActivityTimeUtc": "2025-01-11T21:20:54.4071694Z",
"lastActivityTimeUtc": "2025-01-11T21:25:54.4071694Z",
"lastModifiedTimeUtc": "2025-01-12T17:38:30.9374387Z",
"createdTimeUtc": "2025-01-11T21:31:12.6Z",
"incidentNumber": 9,
"additionalData": {
"alertsCount": 1,
"bookmarksCount": 0,
"commentsCount": 0,
"alertProductNames": [
"Azure Sentinel"
],
"tactics": [
"CredentialAccess"
],
"techniques": [
"T1003"
],
"providerIncidentUrl": "https://security.microsoft.com/incidents/12?tid=96229911-df4d-45c2-9405-73ab8f96cafd"
},
"relatedAnalyticRuleIds": [
"/subscriptions/7ea3f2ec-dc86-48ed-82ee-68ce38406e73/resourceGroups/mssentinel/providers/Microsoft.OperationalInsights/workspaces/mssentinel/providers/Microsoft.SecurityInsights/alertRules/a41f694c-c0f9-4c59-a069-2040601eeffc"
],
"incidentUrl": "https://portal.azure.com/#asset/Microsoft_Azure_Security_Insights/Incident/subscriptions/7ea3f2ec-dc86-48ed-82ee-68ce38406e73/resourceGroups/mssentinel/providers/Microsoft.OperationalInsights/workspaces/mssentinel/providers/Microsoft.SecurityInsights/Incidents/f2731fc2-a8f5-4e35-929e-c2b37cdb9561",
"providerName": "Microsoft XDR",
"providerIncidentId": "12"
}
and the call to get the single alert returns. Again, this is the “properties” field converted into JSON.
{
"systemAlertId": "a02694db-1491-0647-f7ff-20daa3bb2c13",
"tactics": [
"CredentialAccess"
],
"alertDisplayName": "Incident from Archie Dog ",
"description": "Archie Dog's computer, Computer 2 , created an incident on 2025-01-10T00:00:00.0000000Z ",
"confidenceLevel": "Unknown",
"severity": "Medium",
"vendorName": "Microsoft",
"productName": "Azure Sentinel",
"productComponentName": "Scheduled Alerts",
"alertType": "f2801fde-c623-4892-af2a-4bb324457f3a_a41f694c-c0f9-4c59-a069-2040601eeffc",
"processingEndTime": "2025-01-12T17:35:51.39Z",
"status": "InProgress",
"endTimeUtc": "2025-01-11T21:25:54.4071694Z",
"startTimeUtc": "2025-01-11T21:20:54.4071694Z",
"timeGenerated": "2025-01-11T21:31:12.4733333Z",
"providerAlertId": "3ffcc4d5-cbca-480d-9ff2-acd834bfee98",
"alertLink": "https://security.microsoft.com/alerts/sn3ffcc4d5-cbca-480d-9ff2-acd834bfee98?tid=96229911-df4d-45c2-9405-73ab8f96cafd",
"resourceIdentifiers": [
{
"type": "LogAnalytics",
"workspaceId": "f2801fde-c623-4892-af2a-4bb324457f3a"
}
],
"additionalData": {
"MitreTechniques": "[\"T1589\",\"T0820\",\"T1003\",\"T1589.003\",\"T1003.001\"]",
"Search Query Results Overall Count": "2",
"OriginalProductName": "Azure Sentinel",
"OriginalProductComponentName": "Scheduled Alerts"
},
"friendlyName": "Incident from Archie Dog "
}
Graph API
There are different ways to call the Graph API, just like calling Microsoft Sentinel’s API. You can, of course, make a direct call to the REST API via a URL. Then there are many different ways to call the APIs using different program languages, including PowerShell.
If you are going to use PowerShell, you will need to download the PowerShell client library, available at https://aka.ms/pshellsdk and you can more information about the APIs at https://aka.ms/pshellsdkdocs.
It should be noted that you will need to connect to your tenant using “Connect-MgGraph”. You will also need to specify which permissions you want by passing in the values to the “Scopes” parameter. In the case of the incidents, it would be “SecurityIncident.Read.All” and “SecurityIncident.ReadWrite.All” so the call would be:
Connect-MgGraph -Scopes "SecurityIncident.Read.All","SecurityIncident.ReadWrite.All"
Now, the great thing about using the Graph API is there is a third method that Microsoft has made available called the Microsoft Graph Explorer available at Graph Explorer | Try Microsoft Graph APIs – Microsoft Graph. This is an amazing tool that makes it really easy to test out different calls and see what the results are that have been returned. It will also tell you the call you need to make using the various support programming languages to mimic what you just ran. Very cool!
Getting the incidents
Using this tool, I can easily make a call to get all the incidents by making a call to “https://graph.microsoft.com/v1.0/security/incidents” This will return all the incidents that are part of my tenant. Since this is a REST API, I can easily just have the latest one returned by adding “?$top=1” to the end of the line.
Making this call will return the basic information as shown below (converted into JSON):
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#security/incidents",
"@microsoft.graph.tips": "Use $select to choose only the properties your app needs, as this can lead to performance improvements. For example: GET security/incidents?$select=assignedTo,classification",
"value": [
{
"id": "12",
"tenantId": "96229911-df4d-45c2-9405-73ab8f96cafd",
"status": "inProgress",
"incidentWebUrl": "https://security.microsoft.com/incidents/12?tid=96229911-df4d-45c2-9405-...",
"redirectIncidentId": null,
"displayName": "Incident from Archie Dog on multiple endpoints",
"createdDateTime": "2025-01-11T21:31:12.6Z",
"lastUpdateDateTime": "2025-01-12T17:35:51.4033333Z",
"assignedTo": "GaryBushey@GABTest419.onmicrosoft.com",
"classification": "truePositive",
"determination": "malware",
"severity": "medium",
"customTags": [],
"systemTags": [],
"description": null,
"lastModifiedBy": "User-GaryBushey@GABTest419.onmicrosoft.com",
"resolvingComment": "",
"summary": null,
"comments": []
}
]
}
You can get more information about the various calls you can make and the options at Microsoft Graph REST API v1.0 endpoint reference – Microsoft Graph v1.0 | Microsoft Learn For this example, we care about the “Security” calls that can be made. BTW, if you type in the “?” at the end of the line, the Graph Explorer will show you some of the options available. The same goes for if you add an “&” at the end to have a second, or more, option.
You can also make a call to “https://graph.microsoft.com/v1.0/security/alerts” to get all the alerts but it is kind of difficult to map the alerts to the incidents. Luckily, the Graph API provides the “expand” option. By adding this to the end of the URL you are calling, and then specifying what you want to expand, you can see all the alerts that are part of the incident as well.
So, we could make a call to “https://graph.microsoft.com/v1.0/security/incidents?$top=1&$expand=alerts” to get the incident and all the alerts in one call. Much easier than with the Microsoft Sentinel REST API.
If we make this call, we will get:
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#security/incidents(alerts())",
"@microsoft.graph.tips": "Use $select to choose only the properties your app needs, as this can lead to performance improvements. For example: GET security/incidents?$select=assignedTo,classification",
"value": [
{
"id": "12",
"tenantId": "96229911-df4d-45c2-9405-73ab8f96cafd",
"status": "inProgress",
"incidentWebUrl": "https://security.microsoft.com/incidents/12?tid=96229911-df4d-45c2-9405-73ab8f96cafd",
"redirectIncidentId": null,
"displayName": "Incident from Archie Dog on multiple endpoints",
"createdDateTime": "2025-01-11T21:31:12.6Z",
"lastUpdateDateTime": "2025-01-11T21:34:34.3033333Z",
"assignedTo": "GaryBushey@GABTest419.onmicrosoft.com",
"classification": "unknown",
"determination": "unknown",
"severity": "medium",
"customTags": [],
"systemTags": [],
"description": null,
"lastModifiedBy": "User-GaryBushey@GABTest419.onmicrosoft.com",
"resolvingComment": "",
"summary": null,
"comments": [],
"alerts": [
{
"id": "sn3ffcc4d5-cbca-480d-9ff2-acd834bfee98",
"providerAlertId": "3ffcc4d5-cbca-480d-9ff2-acd834bfee98",
"incidentId": "12",
"status": "inProgress",
"severity": "medium",
"classification": null,
"determination": null,
"serviceSource": "microsoftSentinel",
"detectionSource": "scheduledAlerts",
"productName": "Microsoft Sentinel",
"detectorId": "f2801fde-c623-4892-af2a-4bb324457f3a_a41f694c-c0f9-4c59-a069-204",
"tenantId": "96229911-df4d-45c2-9405-73ab8f96cafd",
"title": "Incident from Archie Dog ",
"description": "Archie Dog's computer, Computer 2 , created an incident on 2025-01-10T00:00:00.0000000Z ",
"recommendedActions": "",
"category": "CredentialAccess",
"assignedTo": "GaryBushey@GABTest419.onmicrosoft.com",
"alertWebUrl": "https://security.microsoft.com/alerts/sn3ffcc4d5-cbca-480d-9ff2-acd834bfee98?tid=96229911-df4d-45c2-9405-73ab8f96cafd",
"incidentWebUrl": "https://security.microsoft.com/incidents/12?tid=96229911-df4d-45c2-9405-73ab8f96cafd",
"actorDisplayName": null,
"threatDisplayName": null,
"threatFamilyName": null,
"mitreTechniques": [
"T1589",
"T0820",
"T1003",
"T1589.003",
"T1003.001"
],
"createdDateTime": "2025-01-11T21:31:12.4733333Z",
"lastUpdateDateTime": "2025-01-11T21:34:34.3Z",
"resolvedDateTime": null,
"firstActivityDateTime": "2025-01-11T21:20:54.4071694Z",
"lastActivityDateTime": "2025-01-11T21:25:54.4071694Z",
"systemTags": [],
"alertPolicyId": "a41f694c-c0f9-4c59-a069-2040601eeffc",
"comments": [],
"evidence": [
{
"@odata.type": "#microsoft.graph.security.userEvidence",
"createdDateTime": "2025-01-11T21:31:12.5433333Z",
"verdict": "unknown",
"remediationStatus": "none",
"remediationStatusDetails": null,
"roles": [],
"detailedRoles": [],
"tags": [],
"stream": null,
"userAccount": {
"accountName": "Gary Bushey",
"domainName": null,
"userSid": null,
"azureAdUserId": null,
"userPrincipalName": null,
"displayName": null
}
},
{
"@odata.type": "#microsoft.graph.security.userEvidence",
"createdDateTime": "2025-01-11T21:31:12.5433333Z",
"verdict": "unknown",
"remediationStatus": "none",
"remediationStatusDetails": null,
"roles": [],
"detailedRoles": [],
"tags": [],
"stream": null,
"userAccount": {
"accountName": "Archie Dog",
"domainName": null,
"userSid": null,
"azureAdUserId": null,
"userPrincipalName": null,
"displayName": null
}
},
{
"@odata.type": "#microsoft.graph.security.deviceEvidence",
"createdDateTime": "2025-01-11T21:31:12.5433333Z",
"verdict": "unknown",
"remediationStatus": "none",
"remediationStatusDetails": null,
"roles": [],
"detailedRoles": [],
"tags": [],
"firstSeenDateTime": null,
"mdeDeviceId": null,
"azureAdDeviceId": null,
"deviceDnsName": "Computer1",
"hostName": null,
"ntDomain": null,
"dnsDomain": null,
"osPlatform": null,
"osBuild": null,
"version": null,
"healthStatus": null,
"riskScore": null,
"rbacGroupId": null,
"rbacGroupName": null,
"onboardingStatus": null,
"defenderAvStatus": null,
"lastIpAddress": null,
"lastExternalIpAddress": null,
"ipInterfaces": [],
"vmMetadata": null,
"loggedOnUsers": []
},
{
"@odata.type": "#microsoft.graph.security.deviceEvidence",
"createdDateTime": "2025-01-11T21:31:12.5433333Z",
"verdict": "unknown",
"remediationStatus": "none",
"remediationStatusDetails": null,
"roles": [],
"detailedRoles": [],
"tags": [],
"firstSeenDateTime": null,
"mdeDeviceId": null,
"azureAdDeviceId": null,
"deviceDnsName": "Computer 2",
"hostName": null,
"ntDomain": null,
"dnsDomain": null,
"osPlatform": null,
"osBuild": null,
"version": null,
"healthStatus": null,
"riskScore": null,
"rbacGroupId": null,
"rbacGroupName": null,
"onboardingStatus": null,
"defenderAvStatus": null,
"lastIpAddress": null,
"lastExternalIpAddress": null,
"ipInterfaces": [],
"vmMetadata": null,
"loggedOnUsers": []
},
{
"@odata.type": "#microsoft.graph.security.ipEvidence",
"createdDateTime": "2025-01-11T21:31:12.5433333Z",
"verdict": "unknown",
"remediationStatus": "none",
"remediationStatusDetails": null,
"roles": [],
"detailedRoles": [],
"tags": [],
"ipAddress": "192.18.0.1",
"countryLetterCode": null,
"stream": null,
"location": null
},
{
"@odata.type": "#microsoft.graph.security.ipEvidence",
"createdDateTime": "2025-01-11T21:31:12.5433333Z",
"verdict": "unknown",
"remediationStatus": "none",
"remediationStatusDetails": null,
"roles": [],
"detailedRoles": [],
"tags": [],
"ipAddress": "192.168.0.2",
"countryLetterCode": null,
"stream": null,
"location": null
}
],
"additionalData": {
"OriginalAlertProductName": "Microsoft Sentinel",
"OriginalAlertProviderName": "Azure Sentinel",
"OriginatingAlertSource": "Azure Sentinel",
"Trigger Operator": "GreaterThan",
"Trigger Threshold": "0",
"Correlation Id": "0cd9729b-7d63-4a35-9963-86cec01a4c00",
"Search Query Results Overall Count": "2",
"Data Sources": "[]",
"Analytic Rule Ids": "[\"a41f694c-c0f9-4c59-a069-2040601eeffc\"]",
"Event Grouping": "SingleAlert",
"Analytic Rule Name": "Test rule",
"ProcessedBySentinel": "True",
"Alert generation status": "Full alert created",
"SystemAlertId": "a02694db-1491-0647-f7ff-20daa3bb2c13",
"Query Start Time UTC": "2025-01-11 21:20:54Z",
"Query End Time UTC": "2025-01-11 21:25:55Z",
"Query Period": "00:05:00",
"AlertType": "f2801fde-c623-4892-af2a-4bb324457f3a_a41f694c-c0f9-4c59-a069-2040601eeffc",
"WorkspaceName": "mssentinel",
"Custom Details": "{\n \"EventDate\": [\n \"2025-01-11T00:00:00Z\",\n \"2025-01-10T00:00:00Z\"\n ]\n}",
"Query": "// The query_now parameter represents the time (in UTC) at which the scheduled analytics rule ran to produce this alert.\nset query_now = datetime(2025-01-11T21:25:54.4071694Z);\nlet X = datatable(User: string, Date: datetime, Host: string, IPAddress: string) [\r\n\"Gary Bushey\", datetime(2025-01-11), \"Computer1\",\"192.18.0.1\",\r\n\"Archie Dog\", datetime(2025-01-10),\"Computer 2\", \"192.168.0.2\"];\r\nX",
"WorkspaceId": "f2801fde-c623-4892-af2a-4bb324457f3a",
"InvestigationState": 8192
}
}
]
}
]
}
As you can see, it provides more information than just the alerts. The “evidence” provides incident information and the “additionalData” field provides the additional data you would see if you queried for the incident.
Summary
When connecting your Microsoft Sentinel instance to Microsoft Defender, you get more options on how to get the incident/alert data. This article showed you how to use the Microsoft Graph API to get that data. You could also use the APIs to update data as well as obtaining a lot more data. Go to the URLs listed in the blog post to get more inforamtion.