Another quick post. This time we combine Advanced Hunting Kusto Query Language (KQL) queries and Microsoft PowerShell Graph SDK.

We will use the same Advanced Hunting Kusto Query Language (KQL) as before:

EmailEvents
| summarize Recipients= make_list(RecipientEmailAddress) by Subject, 
NetworkMessageId
| project Subject, Recipients, NetworkMessageId

The PowerShell is also mostly the same with a few changes.

# Connect to the Graph using the App registration details

Connect-MgGraph `
	-ClientId "05c53143-7c86-48b8-ac78" `
	-TenantId "4510da24-0f43-48d3-837d" `
	-CertificateThumbprint "3F813D3DAC8E3613199359D23AEBA"

However, we need to adjust the App registration API permissions to include the following:

  • SecurityEvents.ReadWrite.All
  • ThreatHunting.Read.All

Remember, these permissions will also need admin consent.

Now for the PowerShell:

# Define the Query

$query = "EmailEvents
| summarize Recipients = make_list(RecipientEmailAddress) by Subject, 
NetworkMessageId
| project Subject, Recipients, NetworkMessageId"

# Create the JSON body

$body = @{
    Query = $query
} | ConvertTo-Json

# Invoke the Microsoft Graph API to run the hunting query

$result = Invoke-MgGraphRequest `
    -Method POST `
    -Uri "https://graph.microsoft.com/v1.0/security/runHuntingQuery" `
    -Body $body

# Process the results and create rows for each item with the specified columns

$table = $result.results | ForEach-Object {
    [PSCustomObject]@{
        Subject             = $_.Subject
        RecipientList       = $_.Recipients
        NetworkMessageId    = $_.NetworkMessageId
    }
}

# Display the table

$table | Format-Table

Here is the full code:

Connect-MgGraph `
    -ClientId "<ClientId>" `
    -TenantId "<TenantId>" CertificateThumbprint`
    -CertificateThumbprint "<>"

$query = "EmailEvents
| summarize Recipients = make_list(RecipientEmailAddress) by Subject, 
NetworkMessageId
| project Subject, Recipients, NetworkMessageId"

$body = @{
    Query = $query
} | ConvertTo-Json

$result = Invoke-MgGraphRequest `
    -Method POST `
    -Uri "https://graph.microsoft.com/v1.0/security/runHuntingQuery" `
    -Body $body

$table = $result.results | ForEach-Object {
    [PSCustomObject]@{
        Subject             = $_.Subject
        RecipientList       = $_.Recipients
        NetworkMessageId    = $_.NetworkMessageId
    }
}

$table | Format-Table

After executing this code will return the same values that the Kusto Query Language (KQL) returned within Advance Hunting. I hope this is helpful, happy hunting 🙂