Adding Conditional Logic with iff()
Some investigations only need a simple answer.
Was the sign-in successful or failed? Was the email delivered or blocked? Does this command line contain a suspicious pattern or not?
This is where iff() becomes useful. It allows defenders to create a new value based on a true-or-false condition.
In this Agent Foskett Academy lesson, you will learn how defenders use the KQL iff() function to create simple investigation labels, flag suspicious activity and make Microsoft Defender XDR and Microsoft Sentinel results easier to triage.
Lesson overview
Learn how iff() helps defenders create simple true-or-false labels inside KQL investigation results.
Why iff() matters
This makes it ideal for simple investigation labels where you do not need many categories.
If case() is useful for several possible labels, iff() is useful when the question is simple and direct.
Investigation scenario
The analyst does not need a complex scoring model yet. They need simple labels that answer clear investigation questions.
By using iff() with extend, each row can be marked with a useful true-or-false style label before the evidence is reviewed.
Step 1 — Flag delivered emails that need review
- 1
- 2
- 3
- 4
- 5
- 6
EmailEvents | where Timestamp > ago(7d) | extend ReviewStatus = iff(DeliveryAction == "Delivered", "Needs review", "Already handled") | project Timestamp, SenderFromAddress, RecipientEmailAddress, Subject, DeliveryAction, ReviewStatus | order by Timestamp desc
Step 2 — Flag failed sign-ins
- 1
- 2
- 3
- 4
- 5
- 6
SigninLogs | where TimeGenerated > ago(7d) | extend SignInStatus = iff(ResultType != "0", "Failed sign-in", "Successful sign-in") | project TimeGenerated, UserPrincipalName, IPAddress, Location, ResultType, SignInStatus | order by TimeGenerated desc
Step 3 — Flag risky PowerShell command lines
- 1
- 2
- 3
- 4
- 5
- 6
- 7
DeviceProcessEvents | where Timestamp > ago(7d) | where FileName in~ ("powershell.exe", "pwsh.exe") | extend PowerShellRisk = iff(ProcessCommandLine has_any ("EncodedCommand", "DownloadString"), "High risk command", "No obvious high-risk pattern") | project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, PowerShellRisk | order by Timestamp desc
How iff() works
It is short, readable and useful when the investigation decision only has two possible outcomes.
Step 4 — Create a simple external sender flag
- 1
- 2
- 3
- 4
- 5
- 6
- 7
EmailEvents | where Timestamp > ago(30d) | extend SenderDomain = tostring(split(SenderFromAddress, "@")[1]) | extend SenderType = iff(SenderDomain endswith "gemxit.au", "Internal sender", "External sender") | project Timestamp, SenderFromAddress, SenderDomain, RecipientEmailAddress, Subject, SenderType | order by Timestamp desc
iff() compared with case()
Common investigation uses
Common mistakes
What you learned
Related Agent Foskett Academy lessons
Continue learning with Using has_any to Find Suspicious Text, KQL Threat Hunting Guide and Microsoft Security.
Develop IT. Protect IT. GEMXIT PTY LTD | GEMXIT UK LTD