Lesson 33 — From Hunting Query to Analytics Rule
A hunting query found something useful.
You ran it again — and found the same type of activity.
At some point, repeatedly asking the same question by hand stops being hunting. It becomes a candidate for detection engineering.

What you will learn
Turn repeatable hunting logic into an operational detection.
Learning objectives
- Recognise when hunting logic is suitable for automated detection.
- Prepare hunting KQL for scheduled execution.
- Add scheduling, thresholds, entities and alert context.
- Test the resulting analytics rule before enabling it.
- Understand when a hunting query should remain a hunt.
The investigation
An analyst has a hunting query for repeated failed sign-ins from one IP address across multiple accounts.
It keeps finding activity worth investigating. The question is no longer whether the KQL works — it is whether the behaviour should be monitored automatically.
Hunting and detection answer different questions
| Hunting query | Analytics rule |
|---|---|
| Analyst-driven and exploratory | Automated and repeatable |
| Can tolerate broader results | Must control alert noise |
| Analyst chooses when to run it | Frequency and lookup period are configured |
| Results are reviewed manually | Matching results can generate alerts and incidents |
The promotion path
Do not automate every hunt
Some hunting queries are deliberately broad because a human analyst provides the context.
If a query finds hundreds of harmless anomalies for every useful result, converting it directly into an alert rule simply moves the hunting workload into the incident queue.
Look for repeatable value
A good candidate repeatedly identifies behaviour that deserves timely analyst attention and can be described with stable logic.
The stronger the hypothesis, the easier it is to define what should generate an alert.
Start with the hunting query
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
SigninLogs
| where ResultType != "0"
| summarize FailedAttempts = count(),
TargetUsers = dcount(UserPrincipalName),
Users = make_set(UserPrincipalName, 20)
by IPAddress
| where FailedAttempts >= 20 and TargetUsers >= 5As a hunt, the analyst can change the selected time range, inspect the IP addresses and pivot into the underlying sign-in evidence.
Step 1 — define what should alert
Write the production hypothesis in plain language: “Alert when one source IP generates at least 20 failed sign-ins against five or more distinct accounts during the rule's lookup period.”
Step 2 — investigate existing results
Review previous matches. Which were genuinely suspicious? Which were scanners, test systems, stale applications or expected business activity?
This evidence tells you what must be tuned before automation.
Step 3 — make the result useful to the rule
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
SigninLogs
| where ResultType != "0"
| summarize FailedAttempts = count(),
TargetUsers = dcount(UserPrincipalName),
Users = make_set(UserPrincipalName, 20),
FirstSeen = min(TimeGenerated),
LastSeen = max(TimeGenerated)
by IPAddress
| where FailedAttempts >= 20 and TargetUsers >= 5The output now contains the source IP, event volume, affected-user count and time bounds — useful context for the analyst receiving the alert.
Step 4 — choose frequency and lookup
The hunting page lets an analyst choose when to run the query. A scheduled rule needs an intentional execution frequency and lookup period.
Overlapping windows can repeatedly see the same activity; windows that are too narrow can miss slower behaviour.
Step 5 — decide how thresholds work
The KQL threshold should describe the suspicious behaviour. The analytics rule's result threshold determines whether returned results generate an alert.
Do not use the wizard threshold to rescue poorly defined KQL.
Step 6 — map entities and enrich the alert
The query returns IPAddress, so map it to the IP entity. Add useful custom details such as FailedAttempts, TargetUsers, FirstSeen and LastSeen.
The analyst should be able to understand why the detection fired before reopening the original query.
Step 7 — map MITRE ATT&CK
Map only the behaviour the query actually detects. For password guessing, a Brute Force technique mapping may be appropriate depending on the exact hypothesis and evidence.
Remember Lesson 30: the mapping should never be more confident than the detection.
Step 8 — configure incident behaviour
Decide whether the rule creates incidents and how related alerts should be grouped.
If the same IP repeatedly triggers the rule, grouping choices can materially change the analyst experience.
Microsoft Sentinel can start the conversion
Microsoft's current Sentinel hunting guidance allows a useful hunting query to be promoted into an analytics rule. From hunting results, New alert rule > Create Microsoft Sentinel alert opens the Analytics rule wizard based on the query. Within a hunt, Create analytics rule can also prepopulate the rule name, description and KQL.
You still need to validate scheduling, thresholds, entities, enrichment, MITRE mapping, incident behaviour and alert volume.
Step 9 — test before enabling
Run the production query against historical data and use the rule testing or simulation experience where available.
Confirm that known suspicious examples still match and known benign activity behaves as designed.
Keep the hunting version
Promoting useful logic to an analytics rule does not make the hunt worthless.
The broader hunting version can remain useful for proactive investigation, retrospective analysis and future tuning.
The detection lifecycle
Investigations reveal new evidence. That evidence improves both the hunt and the detection.
Common mistake — copy, save, enable
A hunting query is converted and enabled without reviewing its output. The next shift inherits hundreds of alerts because the query was designed for human exploration, not automated alerting.
Common mistake — no investigation context
The query detects the right behaviour but returns only a count. Include focused fields that explain who, where, when and why the rule fired.
Common mistake — every anomaly becomes an alert
Hunting is allowed to ask broad questions. Production detections need stronger criteria. Rare does not automatically mean malicious.
Common mistake — never revisiting the rule
Environments and attacker behaviour change. A promoted detection still needs tuning and validation after deployment.
Agent Foskett investigation exercise
Some matches are approved administrator scripts, but a small subset consistently deserves investigation.
- Write the exact behaviour you want to detect.
- Identify what distinguishes useful findings from approved administration.
- Return useful entity and investigation fields.
- Choose frequency and lookup period.
- Add only evidence-supported exceptions.
- Map entities and MITRE ATT&CK based on the actual behaviour.
- Test suspicious and benign historical examples before enabling.
Best practices
- Promote repeatable, actionable hunting findings.
- Write the detection hypothesis first.
- Return useful entity and investigation fields.
- Design frequency, lookup and thresholds deliberately.
- Tune with evidence before production.
- Test the complete rule before enabling it.
Agent Foskett takeaway
Hunting discovers the question worth asking.
Detection engineering decides when that question should be asked automatically.
Follow the evidence. Prove the logic. Then automate it.
Related Agent Foskett learning
Continue learning
From Microsoft Sentinel Hunting Query to Analytics Rule
Microsoft Sentinel hunting queries can be promoted into analytics rules when their logic identifies repeatable, actionable behaviour suitable for automated detection. Production rules also require scheduling, thresholds, entity mapping, alert enrichment, incident configuration and testing.
Microsoft Sentinel Lesson 33
This Agent Foskett Microsoft Sentinel Academy lesson explains how to convert useful threat-hunting KQL into a production-ready Microsoft Sentinel analytics rule while preserving investigation context and controlling alert noise.
