Creating New Evidence Fields with extend
Real investigations often need more than the original columns returned by a table.
Defenders may need to extract a sender domain, convert text to lowercase, calculate time differences, classify risky activity or create cleaner evidence fields for reporting.
This is where extend becomes useful. It allows analysts to create new columns from existing evidence, without changing the original data.
In this Agent Foskett Academy lesson, you will learn how defenders use the KQL extend operator to enrich Microsoft Defender XDR and Microsoft Sentinel investigations with clearer, more useful evidence fields.
Lesson overview
Learn how extend helps defenders create new evidence fields that make investigations easier to read, filter and explain.
Why extend matters
This is useful when the evidence exists, but it is not displayed in the way an investigator needs it.
Defenders can use extend to create sender domains, clean usernames, calculate time gaps, classify risky events and prepare cleaner evidence before using project, summarize, join or order by.
Investigation scenario
The raw telemetry contains useful values, but some of them are buried inside longer fields. Email addresses contain domains, sign-in records contain location details and timestamps need to be converted into investigation-friendly fields.
The investigation needs a way to create clean evidence fields before filtering, grouping and reporting the results.
Step 1 — Create a new sender domain field
- 1
- 2
- 3
- 4
- 5
- 6
EmailEvents | where Timestamp > ago(30d) | extend SenderDomain = tostring(split(SenderFromAddress, "@")[1]) | project Timestamp, SenderFromAddress, SenderDomain, RecipientEmailAddress, Subject | sort by Timestamp desc
Step 2 — Normalise values with tolower()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
DeviceProcessEvents | where Timestamp > ago(7d) | extend LowerCommandLine = tolower(ProcessCommandLine) | where LowerCommandLine has_any ("powershell", "encodedcommand", "downloadstring") | project Timestamp, DeviceName, FileName, LowerCommandLine, InitiatingProcessFileName | sort by Timestamp desc
Step 3 — Create a risk label with case()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
SigninLogs | where TimeGenerated > ago(14d) | extend RiskLabel = case( RiskLevelDuringSignIn == "high", "High risk sign-in", RiskLevelDuringSignIn == "medium", "Medium risk sign-in", "Review if unusual" ) | project TimeGenerated, UserPrincipalName, AppDisplayName, IPAddress, RiskLevelDuringSignIn, RiskLabel
What extend does
It does not permanently change the original Microsoft Defender XDR or Sentinel data. It only creates a new field inside the query result.
extend vs project
project chooses which fields appear in the final output.
A common pattern is to use extend first to create useful evidence fields, then use project later to display the clean result.
Step 4 — Summarise using an extended field
- 1
- 2
- 3
- 4
- 5
- 6
- 7
EmailEvents | where Timestamp > ago(30d) | extend SenderDomain = tostring(split(SenderFromAddress, "@")[1]) | summarize EmailCount = count(), Recipients = dcount(RecipientEmailAddress) by SenderDomain | sort by EmailCount desc
Common investigation uses
Common mistakes
What you learned
Related Agent Foskett Academy lessons
Continue learning with Advanced Multi-Value Investigations with mv-apply, KQL Threat Hunting Guide and Microsoft Security.
Develop IT. Protect IT. GEMXIT PTY LTD | GEMXIT UK LTD