Microsoft Defender Email Security KQL Queries
This page is built as a hands-on KQL resource.
It is not written as a story. It is designed as a practical set of Microsoft Defender XDR queries you can copy, run, adapt and understand.
Use it when you need to analyse email authentication, sender alignment, delivery outcomes, repeated targeting and URL click behaviour across your Microsoft 365 environment.
The goal is simple: move from “an email looks suspicious” to evidence you can explain, investigate and act on.
Query library summary
A practical query library for analysts and administrators who want reusable Microsoft Defender KQL examples for EmailEvents, AuthenticationDetails, sender alignment and URL click analysis.
How to read these KQL queries
Baseline query: authentication and spoofing indicators
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
EmailEvents
| where Timestamp > ago(30d)
| where AuthenticationDetails has_any ("spf=fail", "dkim=fail", "dmarc=fail", "spoof")
| project
Timestamp,
SenderFromAddress,
SenderFromDomain,
SenderMailFromAddress,
SenderMailFromDomain,
RecipientEmailAddress,
Subject,
AuthenticationDetails,
ThreatTypes,
DeliveryAction,
NetworkMessageId
| order by Timestamp desc
Query: visible sender versus envelope sender
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
EmailEvents
| where Timestamp > ago(30d)
| where SenderFromDomain != SenderMailFromDomain
| project
Timestamp,
SenderFromAddress,
SenderFromDomain,
SenderMailFromAddress,
SenderMailFromDomain,
RecipientEmailAddress,
Subject,
AuthenticationDetails,
DeliveryAction
| order by Timestamp desc
Query: repeated sender and subject patterns
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
EmailEvents
| where Timestamp > ago(30d)
| where AuthenticationDetails has_any ("spf=fail", "dkim=fail", "dmarc=fail", "spoof")
| summarize
MessageCount = count(),
RecipientCount = dcount(RecipientEmailAddress)
by SenderFromAddress, SenderFromDomain, Subject, DeliveryAction
| where MessageCount >= 3
| order by MessageCount desc
Query: URL click investigation after delivery
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
let SuspiciousMessages =
EmailEvents
| where Timestamp > ago(30d)
| where AuthenticationDetails has_any ("spf=fail", "dkim=fail", "dmarc=fail", "spoof")
| project NetworkMessageId, EmailTime = Timestamp, SenderFromAddress, RecipientEmailAddress, Subject;
SuspiciousMessages
| join kind=inner (
UrlClickEvents
| where Timestamp > ago(30d)
| project NetworkMessageId, ClickTime = Timestamp, AccountUpn, Url, ActionType
) on NetworkMessageId
| order by ClickTime desc
Continue your investigation
Open the KQL hub →
Review DMARC failures →
AuthenticationDetails reveals whether DMARC, SPF and DKIM actually aligned — even when the email was delivered.
Understand authentication →
Review sign-ins, session reuse and location patterns to confirm the activity matches the user.
Review session hijacking →
Look for unusual file activity, after-hours access and patterns that don’t align with the user.
Investigate after-hours file access →
