INSIGHTS
Cybersecurity

Microsoft SC-200: KQL Queries That Matter for Security Analysts

In this article
  1. Start with the question, then choose the table
  2. Reduce the data early with time and selective filters
  3. Use project and extend to shape evidence for humans
  4. Summarize to find patterns that single events cannot show
  5. Join data only when the relationship advances the investigation
  6. Build rare-event and baseline queries with context
  7. Pivot from incident entities instead of starting over
  8. Optimize queries before operationalizing them
  9. Turn good hunts into detections carefully

Kusto Query Language is the working language behind much of Microsoft Sentinel and Defender XDR hunting. Security analysts do not need to memorize every operator. They need to turn investigative questions into efficient queries: narrow the time and data, filter meaningful behavior, shape fields, aggregate patterns, join related evidence, and preserve the entities needed for a response.

The current SC-200 scope explicitly includes KQL for threat hunting and detection. The most valuable queries are not the most complex. They are the ones an analyst can explain, validate, tune, and reuse during a real incident without waiting for a specialist to rewrite them.

Start with the question, then choose the table

Write the investigation question in plain language first: “Which devices executed this hash?” “Which users signed in from this IP?” “Did this account access new cloud resources after privilege elevation?” The question identifies the entities and time range before syntax distracts from the goal.

Then choose the table or normalized parser that actually contains the evidence. Learn a small set of core schemas for the tools you use most, but keep reference documentation close. Guessing field names is slower than checking the schema and can lead to queries that silently return incomplete results.

The SIEM workflow is fundamentally about asking correlated questions across data. KQL is valuable because it lets analysts move from a high-level incident to the raw events that confirm or challenge the story.

Keep a small query notebook organized by investigation task rather than by product. Useful categories include user pivots, device pivots, network pivots, privilege changes, persistence, and data access. This makes KQL a reusable analyst toolkit and reduces the temptation to search the internet for an unreviewed query during an urgent case.

When the question spans products, identify the common entity before choosing syntax. A user object ID, device ID, IP address, or cloud resource ID can provide the thread that links several tables. Starting from the entity helps avoid building a complex query that joins data without a reliable relationship.

Reduce the data early with time and selective filters

Query performance improves when the engine processes less data. Start with a meaningful time range and apply selective where filters early. Searching 30 days of every process event for one device is usually less efficient than filtering the device and recent time before parsing additional fields.

Use exact or case-insensitive comparisons appropriate to the data, and prefer fields that are already typed correctly. Avoid expensive transformations before you know the rows are relevant. The Kusto best-practice guidance repeatedly emphasizes reducing the amount of data processed.

This discipline also improves investigation quality. A tightly scoped query has an understandable purpose and easier-to-review results. Analysts can expand the time window or remove filters deliberately when the evidence suggests a wider scope.

Time filtering should use the column appropriate to the source. Most security tables use TimeGenerated or Timestamp, but imported data can include additional event times. If the wrong time field is used, delayed ingestion may place an event outside the apparent incident window even though the underlying activity belongs there.

Use project and extend to shape evidence for humans

Security tables often contain many fields that are irrelevant to the current question. Use project to keep the columns needed for analysis and extend to create useful derived values. A clean result with time, user, device, action, source IP, and target is easier to inspect than a table with dozens of unused fields.

Rename or calculate fields only when the meaning becomes clearer. Excessive shaping can hide source details that matter later. During early investigation, preserve unique identifiers and original values that allow you to pivot back to the full event.

For repeated workflows, turn common transformations into functions or normalized parsers rather than copying long blocks into every query. Reuse improves consistency and reduces the chance that two analysts interpret the same source differently.

When parsing dynamic JSON fields, first confirm the structure with a small sample. Schema variations and missing keys are common. Parse only after selective filtering, then cast values to the expected type. Defensive parsing keeps a query from breaking when optional properties are absent.

Summarize to find patterns that single events cannot show

The summarize operator can count activity, group by entity, calculate distinct values, and build baselines. This is where many useful hunting questions emerge: accounts with many failed sign-ins, devices contacting many rare domains, users creating unusually many inbox rules, or hosts executing a command across many endpoints.

Choose the grouping fields carefully. Summarizing only by IP may combine many users behind a proxy, while summarizing by user and device may reveal the specific outlier. Use bin() to group time into intervals when the rate of events matters.

Counts are not automatically suspicious. Compare with normal behavior, peer groups, or historical ranges. A threshold becomes meaningful when it separates a plausible attack pattern from known business activity.

For summarize queries, preserve at least one path back to raw evidence. Counts alone can identify an outlier but not explain it. Include example timestamps, source devices, or make_set() values carefully so the analyst can see what produced the aggregate and decide whether to drill down.

Use percentiles, distinct counts, and time buckets when simple averages hide spikes. Security behavior is often bursty: one short period of unusual activity can be important even when the daily average looks normal. Choose an aggregation that preserves the pattern the hypothesis is trying to detect.

Join data only when the relationship advances the investigation

Joins let analysts connect events across tables, but they can also make queries expensive and difficult to reason about. Use them when the relationship is necessary: a sign-in followed by a role change, an endpoint process followed by a network connection, or a threat-intelligence indicator matched to observed activity.

Filter both sides before joining and keep only the columns needed. Understand whether one-to-many results are expected so a join does not multiply rows and create misleading counts. If two sources can be normalized through ASIM, a source-agnostic parser may be simpler than maintaining several joins.

Prefer stable identifiers over display strings. Joining a user object ID to another object ID is safer than joining display names that can change or collide.

If a join becomes hard to explain, consider a staged approach with let statements. Build and validate each side independently, project the join keys, then combine them. This makes troubleshooting easier and helps reviewers verify that the relationship represents the security question rather than an accidental field match.

Build rare-event and baseline queries with context

Rare behavior can be powerful: a new administrative tool on one device, a user authenticating to an unfamiliar application, or a domain contacted by only one endpoint. But rarity is not maliciousness. Add context such as privilege, asset importance, threat intelligence, and sequence before escalating.

Historical baselines need appropriate windows. Too short a baseline treats routine monthly work as rare; too long a window can hide recent organizational change. Security analytics is iterative: inspect results, learn normal patterns, and refine.

A broad threat-intelligence view can suggest what behavior is worth searching for, but the strongest query combines that external idea with local context and available telemetry.

Rare-event logic benefits from exclusions based on business function. A backup service contacting hundreds of systems is not rare for that role, while the same behavior from a user workstation is highly unusual. Add asset class or account type before calling something anomalous.

Pivot from incident entities instead of starting over

During an incident, begin with the known user, device, IP, hash, URL, or cloud resource and expand outward. Search the same indicator across related tables, then follow new entities only when they add evidence. This keeps hunting connected to the case instead of becoming an open-ended exploration.

Use stable variables or let statements for repeated values so the query is easy to change. Preserve the time window around the incident and expand it only when you need to look before initial access or after containment.

When a useful pivot becomes common, save it as a hunting query or function. Repeated analyst questions are good candidates for reusable content and sometimes for new detections.

Use case-sensitive operators when the data semantics require them, but do not add complexity without reason. Many security identifiers are better compared case-insensitively, while hashes and exact command fragments may have different needs. Query correctness comes from understanding the source, not from memorizing one preferred operator.

Optimize queries before operationalizing them

A query that works interactively on a small dataset may time out when scheduled across production. Review expensive joins, parsing, wildcard searches, and large summarize operations. Apply filters early and select only necessary columns before resource-heavy operators.

Advanced hunting and Sentinel have resource limits, so query efficiency affects reliability as well as speed. A slow detection can delay alerts, and a heavy hunting query can frustrate an incident response when time matters most.

Optimization should not change semantics silently. Compare result counts and sample events before and after rewriting a query. Performance improvements are useful only if the security question still receives the same answer.

Performance testing should use realistic production windows. A query that runs quickly over two hours of data can be unusable over the seven-day lookback required by the detection. Measure execution time and result volume at the intended scale before operationalizing the query.

Keep comments in longer production queries. Explain unusual filters, hard-coded exclusions, or parsing assumptions so future analysts know why they exist. A fast query that no one can safely maintain becomes operational debt. Readability is part of reliability for security analytics.

Turn good hunts into detections carefully

A hunting query explores a hypothesis; a detection must run repeatedly and create actionable alerts. Before converting a hunt into a rule, define schedule, lookback, threshold, entity mapping, severity, and false-positive handling. Test it against historical data and recent benign activity.

Custom detections in Defender XDR and analytics rules in Sentinel can operationalize successful queries. The cybersecurity analyst perspective is useful because detection engineering should support triage and response, not merely prove that a clever query can find an event.

Keep the original investigative intent in the rule documentation. Future analysts should understand what behavior the query is looking for and what evidence would make the alert stronger or weaker. Explainable KQL is more valuable than compact KQL.

When a hunt becomes a detection, simplify where possible. Interactive hunting can tolerate exploratory fields and broad output; scheduled detections should return only what is needed for the alert and entity mapping. Smaller, clearer output is easier to investigate and less likely to break automation downstream.

Review converted detections after their first few weeks in production. Real alert volume and analyst feedback often reveal assumptions that historical testing missed. Tune with evidence and preserve the original hunting query for exploratory use.

Filed under Cybersecurity