Run your query in Advanced hunting, then send the same query to Microsoft Graph’s runHuntingQuery to get the results as JSON. The portal’s export button produces a spreadsheet-style file that LogTotal doesn’t read today. Advanced hunting keeps 30 days of data, so anything older has to come from Sentinel or wherever you stream Defender data.
Defender XDR holds endpoint, identity, email and cloud app telemetry in one queryable place, which makes it the first stop in most Microsoft-shop investigations. Prime Core has 17,197 detection rules for Microsoft Defender data, mapped to 659 MITRE ATT&CK techniques. Below is how to pull a slice out, sanitize it, and investigate it for free in LogTotal.
Before you start
Permissions. For Graph, you need the ThreatHunting.Read.All permission. The signed-in user also needs a Defender role that allows advanced hunting.
Limits. Queries time out after a few minutes, and results are capped. Plan to split by time or by device.
The tables. DeviceProcessEvents, DeviceNetworkEvents, DeviceLogonEvents, DeviceFileEvents, DeviceRegistryEvents, DeviceEvents (a mixed bag, including ASR and AMSI events), EmailEvents, IdentityLogonEvents, and AlertInfo with AlertEvidence. The time column is Timestamp.
The examples follow Microsoft’s documentation, checked October 2026.
Step 1: Write the query
DeviceProcessEvents
| where Timestamp between (datetime(2026-10-19) .. datetime(2026-10-20))
| where DeviceName startswith "ws-042"
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine,
InitiatingProcessFileName, InitiatingProcessCommandLine, SHA256
Run it in the portal first. Device names in Defender are often FQDNs, which is why startswith works better than ==.
Step 2: Export through Microsoft Graph
Connect-MgGraph -Scopes "ThreatHunting.Read.All"
$kql = @"
DeviceProcessEvents
| where Timestamp between (datetime(2026-10-19) .. datetime(2026-10-20))
| where DeviceName startswith "ws-042"
"@
$resp = Invoke-MgGraphRequest -Method POST `
-Uri "https://graph.microsoft.com/v1.0/security/runHuntingQuery" `
-Body (@{ Query = $kql } | ConvertTo-Json) -ContentType "application/json"
$resp.results | ForEach-Object { $_ | ConvertTo-Json -Depth 10 -Compress } |
Out-File ws042_proc_1019.jsonl -Encoding utf8
Each row comes back as one JSON object per line. For several days or several devices, loop over day-sized windows to stay under the limits.
Step 3: Upload, sanitize and review in LogTotal
- Upload. Open logtotal.com and drop in the .jsonl file.
- Sanitize.
- Review.
When it goes wrong
| Symptom | Likely cause | Fix |
|---|---|---|
| 403 from Graph | Missing ThreatHunting.Read.All consent or Defender role | Grant consent; check your role |
| Query times out or returns partial results | Too much data in one query | Narrow the time window or the device set |
| Nothing older than 30 days | Advanced hunting retention | Use Sentinel or your streaming destination |
| Row count stops at a round number | Result cap | Split the window |
| No rows for a known device | Name mismatch (short name vs FQDN) | Use startswith or has |
FAQ
Can I get the raw EVTX from a device?
Yes, with Live Response in Defender for Endpoint: getfile pulls files, including exported EVTX, from a machine.
Is this the same as Sentinel?
No, though they overlap in the unified Defender portal. Sentinel keeps longer history.