Agent Foskett Academy • Lesson 16 • Using let Statements to Reuse Evidence

Using let Statements to Reuse Evidence

Longer investigations can become messy very quickly.
The same user appears again.
The same device appears again.
The same IP address appears again.
The same filtered evidence is needed in more than one place.

A let statement helps keep the investigation clean.

In this Agent Foskett Academy lesson, you will learn how defenders use let statements to store values, create reusable evidence sets and build clearer Microsoft Defender XDR and Microsoft Sentinel investigations.

Agent Foskett Academy lesson explaining how to use let statements in KQL investigations
Lesson overview

Learn how to use let statements to reuse usernames, devices, IP addresses and filtered evidence sets across a KQL investigation.

Create reusable values
Build reusable evidence sets
Keep investigations cleaner
🧩 let statements make investigations easier to reuse.
Instead of typing the same user, device, IP address or evidence filter again and again, define it once and reuse it.
Review Lesson 15 →

Why let statements matter

A defender often starts with one clue.

It might be a username, a device name, an IP address, a sender, a URL or a suspicious process.

A let statement lets you store that clue once, give it a useful name and reuse it throughout the investigation.
Reduce repetitionStore common values once instead of typing them throughout the query.
Make queries clearerGive evidence meaningful names so another analyst can understand the investigation faster.
Reuse filtered evidenceCreate a filtered evidence set once, then summarize, join or review it in different ways.

Investigation scenario

A user received a suspicious email and clicked a link.

The analyst needs to check the same user across email events, URL clicks and sign-in activity.

Instead of typing the user account repeatedly, the analyst creates a reusable value with let.

Step 1 — Create a simple reusable value

A simple let statement can store a username, device name, IP address, URL or any other value you want to reuse.
simple-let-value.kql
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
let targetUser = "user@contoso.com";
SigninLogs
| where TimeGenerated > ago(7d)
| where UserPrincipalName == targetUser
| take 100

How this works

The first line creates a named value called targetUser.

Every time the query uses targetUser, KQL treats it as the value user@contoso.com.

If the investigation changes to another user, you only need to update one line.
letStarts the reusable value or evidence set.
targetUserThe name you choose for the value. Clear names make investigations easier to read.
SemicolonThe let statement ends with a semicolon before the next part of the query starts.

Step 2 — Reuse the value across different tables

The same target user can be reused across multiple Microsoft security tables.
reuse-target-user.kql
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
let targetUser = "user@contoso.com";
EmailEvents
| where Timestamp > ago(7d)
| where RecipientEmailAddress == targetUser
| project Timestamp, RecipientEmailAddress, SenderFromAddress, Subject, DeliveryAction
| sort by Timestamp desc

Step 3 — Create a reusable evidence set

A let statement can also store a filtered set of results. This is very useful when the same evidence needs to be reviewed more than once.
reusable-evidence-set.kql
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
let failedSignins =
SigninLogs
| where TimeGenerated > ago(7d)
| where ResultType != 0;
failedSignins
| summarize FailedAttempts = count() by UserPrincipalName
| sort by FailedAttempts desc

Step 4 — Reuse the same evidence in more than one way

Once the evidence set has been defined, you can use it to answer different investigation questions.
reuse-evidence-two-ways.kql
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
let failedSignins =
SigninLogs
| where TimeGenerated > ago(7d)
| where ResultType != 0;
failedSignins
| summarize FailedAttempts = count() by UserPrincipalName;
failedSignins
| summarize UniqueIPs = dcount(IPAddress) by UserPrincipalName
| sort by UniqueIPs desc

Important investigation tip

Let statements are not only about making a query shorter.

They help make the investigation easier to explain. When the query uses names like targetUser, suspiciousDevice or failedSignins, the logic becomes easier to follow.
Name the evidence clearlyUse names that explain the purpose, not vague names like data1 or table2.
Define earlyPut important let statements near the top of the query so the investigation starts with context.
Keep it readableUse let when it makes the query easier to understand, not just because you can.

Step 5 — Use let in a Defender XDR timeline

Let statements work especially well when building timelines from different tables.
let-investigation-timeline.kql
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
let targetUser = "user@contoso.com";
let emailActivity = EmailEvents
| where Timestamp > ago(7d)
| where RecipientEmailAddress == targetUser
| project TimelineTime = Timestamp, EventType = "Email delivered", Account = RecipientEmailAddress, Detail = Subject;
let urlActivity = UrlClickEvents
| where Timestamp > ago(7d)
| where AccountUpn == targetUser
| project TimelineTime = Timestamp, EventType = "URL clicked", Account = AccountUpn, Detail = Url;
union emailActivity, urlActivity
| sort by TimelineTime asc

When to use let statements

Use let statements when the query is starting to become an investigation, not just a quick lookup.
User investigationsStore the target user once and reuse it across email, sign-in, device and cloud activity.
Device investigationsStore a device name or device ID and use it across process, network, file and logon events.
IP or URL investigationsStore suspicious infrastructure once and reuse it across tables that record network or click activity.

When not to overuse let

A let statement should make the investigation clearer.

If the query is only one or two lines, or the value is only used once, a let statement may not add much value.
Avoid unnecessary complexityDo not add let statements just to make a simple query look advanced.
Avoid vague namesNames like x, y or temp do not help another analyst understand the investigation.
Avoid hiding the logicIf too many let statements make the query harder to follow, simplify the structure.
🎓 Agent Foskett Academy — Reuse the evidence
You now understand how let statements help defenders build cleaner, reusable and more structured KQL investigations.
Return to Academy

What you learned

In this lesson, you learned how to use let statements to reuse evidence in KQL.
Reusable valuesYou used let to store target users and other investigation clues.
Reusable evidence setsYou created filtered result sets that can be reused later in the same investigation.
Cleaner investigationsYou made longer KQL queries easier to read, explain and update.

Continue your investigation

The next step is learning how to create reusable investigation parameters for users, devices, IP addresses and time ranges.
Agent Foskett Academy Return to the full Academy learning path and review earlier KQL foundation lessons.
Building Investigation Timelines with KQL Review the previous lesson and see how let statements can support timeline investigations.

Using let Statements to Reuse Evidence

Agent Foskett Academy Lesson 16 teaches defenders how to use let statements in KQL to create reusable values, reusable evidence sets and cleaner Microsoft Defender XDR investigations.

Learn KQL let statements for Microsoft Defender XDR

KQL let statements help analysts store usernames, devices, IP addresses, URLs and filtered evidence so investigation queries are easier to read and maintain.

KQL reusable evidence lesson for Microsoft security analysts

This Agent Foskett Academy lesson explains how to define let statements, reuse evidence sets and build structured investigations inside Microsoft Defender XDR and Microsoft Sentinel.