Normalising Text with tolower() and toupper()
Microsoft security telemetry often contains usernames, domains and email addresses that appear in different letter casing.
One event may show MICROSOFT.COM, another Microsoft.com and another microsoft.com.
Using tolower() and toupper(), defenders can normalise text before comparing, grouping and investigating evidence.
In this lesson, you'll learn how these functions help create cleaner and more reliable Microsoft Defender XDR and Sentinel investigations.
Lesson overview
Learn how tolower() and toupper() help defenders normalise text before comparing investigation evidence.
Why text normalisation matters
A sender domain, user principal name, device name or command-line value may appear with mixed casing depending on the source system, application, operating system or log pipeline.
Normalising text helps defenders compare values fairly, group related evidence together and avoid treating the same indicator as multiple different values.
Investigation scenario
The evidence contains mixed casing across sender domains, user names and command lines.
Before grouping and comparing the results, the analyst creates normalised fields using tolower() and toupper() so the investigation can focus on behaviour instead of formatting differences.
Step 1 — Normalise sender domains in EmailEvents
- 1
- 2
- 3
- 4
- 5
- 6
EmailEvents | where Timestamp > ago(30d) | extend SenderDomainLower = tolower(SenderFromDomain) | summarize EmailCount = count() by SenderDomainLower | order by EmailCount desc
Step 2 — Normalise user names before comparison
- 1
- 2
- 3
- 4
- 5
- 6
SigninLogs | where TimeGenerated > ago(7d) | extend UserLower = tolower(UserPrincipalName) | project TimeGenerated, UserPrincipalName, UserLower, IPAddress, Location, ResultType | order by TimeGenerated desc
Step 3 — Normalise command-line evidence
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
DeviceProcessEvents | where Timestamp > ago(7d) | where FileName in~ ("powershell.exe", "pwsh.exe") | extend CommandLower = tolower(ProcessCommandLine) | where CommandLower has_any ("encodedcommand", "downloadstring", "invoke-webrequest") | project Timestamp, DeviceName, AccountName, FileName, CommandLower | order by Timestamp desc
How tolower() and toupper() work
The toupper() function converts text into uppercase.
Both functions are useful when the investigation needs consistent values before filtering, summarising, joining or reporting.
Step 4 — Use toupper() for consistent reporting labels
- 1
- 2
- 3
- 4
- 5
- 6
- 7
EmailEvents | where Timestamp > ago(30d) | extend DeliveryActionUpper = toupper(DeliveryAction) | summarize TotalEvents = count() by DeliveryActionUpper | order by TotalEvents desc
Normalised text compared with raw text
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