Using matches regex for Pattern Matching
Sometimes a simple text search is not enough.
You are not just looking for one word.
You are looking for a pattern.
A filename that looks random. A URL with a strange structure. A command line carrying encoded content.
That is where matches regex becomes useful.
In this Agent Foskett Academy lesson, you will learn how defenders use the KQL matches regex operator to search for structured patterns across Microsoft Defender XDR and Microsoft Sentinel telemetry.
Lesson overview
Learn how regex-based searches help defenders find suspicious patterns that simple contains, startswith or endswith searches may miss.
Why matches regex matters
That means you can search for shapes in text, such as numbers, file extensions, encoded strings, unusual URL formats or command-line patterns.
It is powerful, but it should be used carefully. Regex can turn a simple hunt into a bowl of alphabet soup if you make it too clever.
Investigation scenario
Several filenames look randomly generated. A URL contains a strange numeric path. A PowerShell command includes encoded content.
Instead of searching for one fixed value, the analyst uses matches regex to find patterns that look suspicious.
Step 1 — Find suspicious script filenames
- 1
- 2
- 3
- 4
- 5
- 6
- 7
DeviceFileEvents | where Timestamp > ago(7d) | where FileName matches regex @"^[a-zA-Z0-9]{{8,}}\.ps1$" | project Timestamp, DeviceName, ActionType, FileName, FolderPath, InitiatingProcessCommandLine | sort by Timestamp desc
Step 2 — Find URLs with unusual numeric paths
- 1
- 2
- 3
- 4
- 5
- 6
- 7
UrlClickEvents | where Timestamp > ago(14d) | where Url matches regex @"/[0-9]{{6,}}" | project Timestamp, AccountUpn, Url, ActionType, ThreatTypes, NetworkMessageId | sort by Timestamp desc
Step 3 — Find encoded PowerShell commands
- 1
- 2
- 3
- 4
- 5
- 6
- 7
DeviceProcessEvents | where Timestamp > ago(7d) | where ProcessCommandLine matches regex @"(?i)-enc(odedcommand)?\s+[A-Za-z0-9+/=]{{20,}}" | project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine | sort by Timestamp desc
What the operator does
A regular expression is a structured search pattern. It can describe letters, numbers, symbols, repeated characters, optional text and word positions.
Start simple. Build the pattern slowly. Test it. Then add complexity only when it helps the investigation.
Step 4 — Find suspicious email subjects
- 1
- 2
- 3
- 4
- 5
- 6
- 7
EmailEvents | where Timestamp > ago(30d) | where Subject matches regex @"(?i)(invoice|payment|remittance).*[0-9]{{4,}}" | project Timestamp, SenderFromAddress, RecipientEmailAddress, Subject, DeliveryAction, ThreatTypes | sort by Timestamp desc
Step 5 — Find executable downloads from URLs
- 1
- 2
- 3
- 4
- 5
- 6
- 7
UrlClickEvents | where Timestamp > ago(30d) | where Url matches regex @"(?i)\.(exe|msi|scr|bat|cmd|ps1)(\?|$)" | project Timestamp, AccountUpn, Url, ActionType, ThreatTypes | sort by Timestamp desc
Step 6 — Use parameters for repeatable regex hunts
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
let SuspiciousFilePattern = @"(?i)\.(exe|scr|bat|cmd|ps1)$"; DeviceFileEvents | where Timestamp > ago(14d) | where FileName matches regex SuspiciousFilePattern | project Timestamp, DeviceName, ActionType, FileName, FolderPath, InitiatingProcessAccountName | sort by Timestamp desc
Investigator notes
But do not make every hunt a regex hunt. If a simple has_any, in, startswith or endswith query does the job, use the simpler option first.
What you learned
Continue your investigation
Continue learning with Using has_any, Using in, KQL Threat Hunting Guide and Microsoft Security.
Develop IT. Protect IT. GEMXIT PTY LTD | GEMXIT UK LTD