Creating Investigation Parameters with KQL
Good investigations need focus.
One user.
One device.
One IP address.
One time window.
But typing those values over and over creates mistakes.
In this Agent Foskett Academy lesson, you will learn how defenders use investigation parameters with let statements to make KQL queries easier to update, easier to reuse and much safer during Microsoft Defender XDR and Microsoft Sentinel investigations.
Lesson overview
Learn how to define investigation values once and reuse them across email, identity, endpoint and network queries.
What are investigation parameters?
Instead of typing the same user, device, IP address or time range multiple times, you define it once with let and refer to it throughout the investigation.
Investigation scenario
The analyst needs to investigate the same account across sign-ins, email events, URL clicks and endpoint activity.
Rather than manually changing the username in every part of the query, the analyst creates investigation parameters at the top.
Step 1 — Create a target user parameter
- 1
- 2
- 3
- 4
- 5
- 6
let targetUser = "user@contoso.com"; SigninLogs | where UserPrincipalName == targetUser | project TimeGenerated, UserPrincipalName, IPAddress, ResultDescription | sort by TimeGenerated desc
Step 2 — Add a time window parameter
- 1
- 2
- 3
- 4
- 5
- 6
- 7
let investigationStart = ago(7d); let targetUser = "user@contoso.com"; SigninLogs | where TimeGenerated > investigationStart | where UserPrincipalName == targetUser | project TimeGenerated, UserPrincipalName, IPAddress, AppDisplayName, ResultDescription
Why this helps
When the next incident comes in, you can change the values at the top of the query without rebuilding the entire investigation.
Step 3 — Use several parameters together
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
let investigationStart = ago(7d); let targetUser = "user@contoso.com"; let suspiciousIP = "203.0.113.10"; SigninLogs | where TimeGenerated > investigationStart | where UserPrincipalName == targetUser | where IPAddress == suspiciousIP | project TimeGenerated, UserPrincipalName, IPAddress, Location, ResultDescription
Step 4 — Reuse parameters across multiple tables
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
let investigationStart = ago(7d); let targetUser = "user@contoso.com"; let emailActivity = EmailEvents | where Timestamp > investigationStart | where RecipientEmailAddress == targetUser | project TimelineTime = Timestamp, EventType = "Email", Account = RecipientEmailAddress, Detail = Subject; let clickActivity = UrlClickEvents | where Timestamp > investigationStart | where AccountUpn == targetUser | project TimelineTime = Timestamp, EventType = "URL click", Account = AccountUpn, Detail = Url; union emailActivity, clickActivity | sort by TimelineTime asc
Step 5 — Add device and IP parameters
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
let investigationStart = ago(7d); let targetDevice = "DESKTOP-01"; let suspiciousIP = "203.0.113.10"; DeviceNetworkEvents | where Timestamp > investigationStart | where DeviceName == targetDevice | where RemoteIP == suspiciousIP | project Timestamp, DeviceName, InitiatingProcessFileName, RemoteIP, RemotePort
Investigator notes
A good rule is simple: if a value controls the investigation, put it near the top.
What you learned
Continue your investigation
Continue learning with Building Investigation Timelines with KQL, Connecting Tables with join, Investigating UrlClickEvents, KQL Threat Hunting Guide and Microsoft Security.
Develop IT. Protect IT. GEMXIT PTY LTD | GEMXIT UK LTD