25 KQL Queries Every SOC Analyst Should Know in 2026
Learn practical Kusto Query Language queries for investigating authentication, account changes, PowerShell, processes, network activity and indicators of compromise.
A Security Operations Center receives thousands or millions of security events. The analyst’s challenge is not simply collecting this data. The challenge is finding the events that matter and turning them into a meaningful investigation.
Kusto Query Language, commonly called KQL, helps analysts search, correlate, summarise and visualise security data in platforms such as Microsoft Sentinel and Microsoft Defender XDR.
This guide contains 25 practical KQL queries for common SOC use cases. Each query includes its purpose, expected data source, investigation context and customisation guidance.
What You Will Learn
- What KQL is and how it differs from SQL
- Which Microsoft security tables SOC analysts commonly use
- How to filter, search, summarise, join and project data
- How to investigate successful and failed logins
- How to identify account and privilege changes
- How to analyse PowerShell and process activity
- How to examine network connections and DNS activity
- How to search for suspicious IP addresses and hashes
- How to build user and endpoint investigation timelines
- How to convert hunting queries into reliable detections
1. What Is KQL?
KQL stands for Kusto Query Language. It is a read-only query language designed to explore and analyse large volumes of structured and semi-structured data.
SOC analysts use KQL to answer questions such as:
- Which users generated repeated login failures?
- Did any failed-login sequence end in a successful login?
- Who created a new account?
- Was a user added to a privileged group?
- Which device executed PowerShell?
- Did a suspicious process connect to an external IP address?
- Where else was a malicious hash observed?
Microsoft’s
official KQL quick reference
documents operators such as where, project,
summarize, join and render.
2. KQL Versus SQL
| Area | KQL | SQL |
|---|---|---|
| Primary purpose | Analytics, telemetry exploration and time-series investigation | Relational database querying and data management |
| Typical structure | Starts with a table and passes data through pipe-separated operators | Uses clauses such as SELECT, FROM and WHERE |
| Security use | SIEM searches, hunting, analytics and investigation | Application and relational database use cases |
| Data modification | Queries are read-only | May support insert, update and delete operations |
Basic KQL structure
SecurityEvent | where TimeGenerated > ago(24h) | where EventID == 4625 | summarize FailedAttempts = count() by Account | order by FailedAttempts desc
The result of each line flows into the next operator through the
| character.
3. Important Microsoft Security Tables
| Table | Typical data | Important dependency |
|---|---|---|
| SecurityEvent | Windows Security events collected into Microsoft Sentinel | Windows Security Events data collection |
| WindowsEvent | Windows event channels collected through Azure Monitor | Appropriate Data Collection Rule |
| SigninLogs | Microsoft Entra interactive sign-in activity | Microsoft Entra data connector and required licensing |
| AuditLogs | Microsoft Entra directory audit activity | Microsoft Entra data connector |
| DeviceLogonEvents | Device logon and authentication activity | Microsoft Defender for Endpoint data |
| DeviceProcessEvents | Process creation and related endpoint activity | Microsoft Defender for Endpoint data |
| DeviceNetworkEvents | Network connections observed on endpoints | Microsoft Defender for Endpoint data |
| DeviceFileEvents | File creation, modification and other file activity | Microsoft Defender for Endpoint data |
| CommonSecurityLog | CEF data from supported network and security devices | Configured CEF connector and source |
Microsoft notes that advanced-hunting tables such as
DeviceProcessEvents are populated by their associated
Microsoft Defender services. A query cannot return data from a source
that has not been deployed and connected.
4. Essential KQL Operators
where
Filters rows using one or more conditions.
| where EventID == 4625
project
Selects, renames and arranges output columns.
| project TimeGenerated, Account, Computer
summarize
Aggregates events using count, distinct count, minimum or maximum.
| summarize count() by Account
bin
Groups timestamps into intervals such as five minutes or one hour.
bin(TimeGenerated, 15m)
order by
Sorts results in ascending or descending order.
| order by Attempts desc
join
Combines related results using one or more shared columns.
| join kind=inner OtherData on Account
extend
Creates a calculated column without removing existing columns.
| extend User = tolower(Account)
let
Assigns a value, expression or table result to a reusable name.
let Lookback = 24h;
5. Twenty-Five Practical KQL Queries
View Recent Windows Security Events
Start by examining recent Windows Security events to understand the table and available columns.
SecurityEvent
| where TimeGenerated > ago(1h)
| project TimeGenerated, Computer, EventID, Activity, Account,
IpAddress, LogonTypeName
| order by TimeGenerated desc
| take 100
Use this query to inspect your data before writing more specific searches. Fields may be empty when the selected event does not populate them.
Find Failed Windows Logins
SecurityEvent
| where TimeGenerated > ago(24h)
| where EventID == 4625
| project TimeGenerated, Computer, Account, IpAddress,
LogonTypeName, FailureReason, SubStatus
| order by TimeGenerated desc
Investigate the account, source address, destination, logon type and failure reason. A failed login may result from user error, an expired password, stale application credentials or malicious activity.
Find Successful Windows Logins
SecurityEvent
| where TimeGenerated > ago(24h)
| where EventID == 4624
| project TimeGenerated, Computer, Account, IpAddress,
LogonTypeName, AuthenticationPackageName
| order by TimeGenerated desc
Successful logins become especially important when they follow repeated failures, originate from unusual systems or involve privileged identities.
Find Failures Followed by a Successful Login
let Failures =
SecurityEvent
| where TimeGenerated > ago(24h)
| where EventID == 4625
| summarize FailedAttempts = count(),
FirstFailure = min(TimeGenerated),
LastFailure = max(TimeGenerated)
by Account, IpAddress, Computer;
let Successes =
SecurityEvent
| where TimeGenerated > ago(24h)
| where EventID == 4624
| summarize FirstSuccess = min(TimeGenerated)
by Account, IpAddress, Computer;
Failures
| where FailedAttempts >= 5
| join kind=inner Successes on Account, IpAddress, Computer
| where FirstSuccess between (LastFailure .. LastFailure + 30m)
| project Account, IpAddress, Computer, FailedAttempts,
FirstFailure, LastFailure, FirstSuccess
| order by FailedAttempts desc
This is a starting pattern. In a production environment, refine account normalisation, handling of missing IP addresses, service accounts, logon types and time-window logic.
Find Accounts with Repeated Login Failures
SecurityEvent
| where TimeGenerated > ago(24h)
| where EventID == 4625
| summarize FailedAttempts = count(),
SourceIPs = dcount(IpAddress),
Computers = make_set(Computer, 10)
by Account, bin(TimeGenerated, 15m)
| where FailedAttempts >= 10
| order by FailedAttempts desc
Review whether the account is a normal user, administrator or service identity. Adjust the threshold after observing normal activity.
Find One Source Targeting Multiple Accounts
SecurityEvent
| where TimeGenerated > ago(24h)
| where EventID == 4625
| where isnotempty(IpAddress)
| summarize FailedAttempts = count(),
TargetedAccounts = dcount(Account),
Accounts = make_set(Account, 20)
by IpAddress, bin(TimeGenerated, 15m)
| where TargetedAccounts >= 5
| order by TargetedAccounts desc
One source failing against many accounts may indicate password spraying, but shared systems, identity proxies or misconfigured applications may produce similar patterns.
Find Account Lockouts
SecurityEvent
| where TimeGenerated > ago(7d)
| where EventID == 4740
| project TimeGenerated, Computer, TargetAccount,
SubjectAccount, CallerComputerName
| order by TimeGenerated desc
The calling computer can help identify the system using an old password or generating repeated failures.
Find Newly Created User Accounts
SecurityEvent
| where TimeGenerated > ago(7d)
| where EventID == 4720
| project TimeGenerated, Computer, TargetAccount,
SubjectAccount, SubjectDomainName
| order by TimeGenerated desc
Validate whether the account creation was approved, who created it and whether the new account was later assigned privileges.
Find Password Reset Attempts
SecurityEvent
| where TimeGenerated > ago(7d)
| where EventID == 4724
| project TimeGenerated, Computer, SubjectAccount,
TargetAccount, Activity
| order by TimeGenerated desc
Review whether the reset followed an approved help-desk process and whether the account showed suspicious activity afterwards.
Find Security-Group Membership Changes
SecurityEvent
| where TimeGenerated > ago(7d)
| where EventID in (4728, 4729, 4732, 4733, 4756, 4757)
| project TimeGenerated, Computer, EventID, Activity,
SubjectAccount, TargetAccount, MemberName
| order by TimeGenerated desc
These events can represent members being added to or removed from global, local or universal security groups. Prioritise changes involving privileged groups.
Find Privileged Logons
SecurityEvent
| where TimeGenerated > ago(24h)
| where EventID == 4672
| project TimeGenerated, Computer, Account,
SubjectLogonId, PrivilegeList
| order by TimeGenerated desc
Event ID 4672 can be noisy. Establish which service and administrative accounts normally receive special privileges before creating an alert.
Find Explicit Credential Use
SecurityEvent
| where TimeGenerated > ago(24h)
| where EventID == 4648
| project TimeGenerated, Computer, SubjectAccount,
TargetAccount, TargetServerName,
ProcessName, IpAddress
| order by TimeGenerated desc
Explicit credentials may be used by legitimate administrative tools, scheduled processes or run-as activity. Investigate the process, source, destination and user context.
Review Recent Process Creation
DeviceProcessEvents
| where Timestamp > ago(1h)
| project Timestamp, DeviceName, AccountName,
FileName, ProcessCommandLine,
InitiatingProcessFileName, SHA1
| order by Timestamp desc
| take 200
The DeviceProcessEvents table requires data from Microsoft
Defender for Endpoint. Use this query to understand normal processes,
users and parent-child relationships.
Find PowerShell Execution
DeviceProcessEvents
| where Timestamp > ago(24h)
| where FileName in~ ("powershell.exe", "pwsh.exe")
| project Timestamp, DeviceName, AccountName,
FileName, ProcessCommandLine,
InitiatingProcessFileName
| order by Timestamp desc
PowerShell is widely used for legitimate administration. Investigate the command line, initiating process, account, device and related network or file activity.
Find Encoded PowerShell Indicators
DeviceProcessEvents
| where Timestamp > ago(7d)
| where FileName in~ ("powershell.exe", "pwsh.exe")
| where ProcessCommandLine has_any
("-enc", "-encodedcommand", "FromBase64String")
| project Timestamp, DeviceName, AccountName,
ProcessCommandLine, InitiatingProcessFileName,
SHA1
| order by Timestamp desc
Encoding is not automatically malicious. Administrators and software may use encoded content legitimately. Treat this query as a hunting lead.
Search Command Lines for Investigation Keywords
let SearchTerms = dynamic([
"whoami",
"net user",
"net localgroup",
"ipconfig",
"systeminfo"
]);
DeviceProcessEvents
| where Timestamp > ago(24h)
| where ProcessCommandLine has_any (SearchTerms)
| project Timestamp, DeviceName, AccountName,
FileName, ProcessCommandLine,
InitiatingProcessFileName
| order by Timestamp desc
These commands are common administrative and troubleshooting tools. Their presence alone does not demonstrate malicious discovery. Evaluate the complete user and process context.
Find Uncommon Processes
DeviceProcessEvents
| where Timestamp > ago(7d)
| summarize ExecutionCount = count(),
Devices = dcount(DeviceName),
FirstSeen = min(Timestamp),
LastSeen = max(Timestamp)
by FileName
| where ExecutionCount <= 5
| order by ExecutionCount asc
Rare does not mean malicious. New software, updates and specialised tools may be uncommon. Use rarity to prioritise review, not to produce a final verdict.
Find Rare Parent-Child Process Relationships
DeviceProcessEvents
| where Timestamp > ago(7d)
| summarize RelationshipCount = count(),
Devices = dcount(DeviceName),
FirstSeen = min(Timestamp),
LastSeen = max(Timestamp)
by InitiatingProcessFileName, FileName
| where RelationshipCount <= 3
| order by RelationshipCount asc
Parent-child relationships help analysts understand how a process started. Compare unusual relationships with normal application behaviour and digital-signature information.
Review Endpoint Network Connections
DeviceNetworkEvents
| where Timestamp > ago(1h)
| where isnotempty(RemoteIP)
| project Timestamp, DeviceName, ActionType,
LocalIP, LocalPort, RemoteIP, RemotePort,
RemoteUrl, InitiatingProcessFileName,
InitiatingProcessCommandLine
| order by Timestamp desc
| take 200
Do not investigate the destination in isolation. Identify the initiating process, user, device, protocol, destination reputation and surrounding activity.
Review DNS-Related Endpoint Events
DeviceNetworkEvents
| where Timestamp > ago(24h)
| where ActionType contains "Dns"
| project Timestamp, DeviceName, ActionType,
RemoteUrl, RemoteIP,
InitiatingProcessFileName,
InitiatingProcessCommandLine
| order by Timestamp desc
Available DNS action types depend on the product and collected telemetry.
First run DeviceNetworkEvents | distinct ActionType to review
the action types present in your environment.
Search for Suspicious IP Addresses
let SuspiciousIPs = dynamic([
"203.0.113.10",
"198.51.100.25"
]);
DeviceNetworkEvents
| where Timestamp > ago(30d)
| where RemoteIP in (SuspiciousIPs)
| project Timestamp, DeviceName, RemoteIP,
RemotePort, RemoteUrl,
InitiatingProcessFileName,
InitiatingProcessCommandLine
| order by Timestamp desc
The addresses above belong to documentation ranges and are placeholders. Replace them with approved indicators from a trusted intelligence source. Confirm indicator validity and time relevance before escalation.
Search for Suspicious File Hashes
let SuspiciousHashes = dynamic([
"REPLACE_WITH_APPROVED_SHA256_VALUE_1",
"REPLACE_WITH_APPROVED_SHA256_VALUE_2"
]);
DeviceFileEvents
| where Timestamp > ago(30d)
| where SHA256 in (SuspiciousHashes)
| project Timestamp, DeviceName, ActionType,
FileName, FolderPath, SHA256,
InitiatingProcessFileName,
InitiatingProcessCommandLine
| order by Timestamp desc
A hash match is stronger than a keyword match, but analysts must still validate the source, file path, action, device and containment status.
Find Windows Audit-Log Clearing
SecurityEvent
| where TimeGenerated > ago(30d)
| where EventID == 1102
| project TimeGenerated, Computer, Account,
SubjectAccount, Activity
| order by TimeGenerated desc
Log clearing deserves rapid review, but maintenance or lab activity may be legitimate. Verify the user, related session, change approval and events immediately before the log was cleared.
Build a Timeline for One User
let UserToInvestigate = "test.user";
union isfuzzy=true
(
SecurityEvent
| where TimeGenerated > ago(24h)
| where Account contains UserToInvestigate
or SubjectAccount contains UserToInvestigate
or TargetAccount contains UserToInvestigate
| project EventTime = TimeGenerated,
SourceTable = "SecurityEvent",
Device = Computer,
User = coalesce(Account, SubjectAccount, TargetAccount),
Activity = strcat("Windows Event ", tostring(EventID), ": ", Activity)
),
(
DeviceProcessEvents
| where Timestamp > ago(24h)
| where AccountName contains UserToInvestigate
| project EventTime = Timestamp,
SourceTable = "DeviceProcessEvents",
Device = DeviceName,
User = AccountName,
Activity = strcat(FileName, " | ", ProcessCommandLine)
)
| order by EventTime asc
Timeline queries help connect authentication and process activity. In production, normalise usernames carefully because different tables may store domains, UPNs and account names differently.
Build a Timeline for One Endpoint
let DeviceToInvestigate = "LAB-WIN01";
union isfuzzy=true
(
DeviceProcessEvents
| where Timestamp > ago(24h)
| where DeviceName startswith DeviceToInvestigate
| project EventTime = Timestamp,
SourceTable = "Process",
DeviceName,
Activity = strcat(FileName, " | ", ProcessCommandLine)
),
(
DeviceNetworkEvents
| where Timestamp > ago(24h)
| where DeviceName startswith DeviceToInvestigate
| project EventTime = Timestamp,
SourceTable = "Network",
DeviceName,
Activity = strcat(
InitiatingProcessFileName,
" connected to ",
RemoteIP,
":",
tostring(RemotePort)
)
),
(
DeviceFileEvents
| where Timestamp > ago(24h)
| where DeviceName startswith DeviceToInvestigate
| project EventTime = Timestamp,
SourceTable = "File",
DeviceName,
Activity = strcat(ActionType, " | ", FolderPath, "\\", FileName)
)
| order by EventTime asc
This query builds a basic process, network and file timeline. Add authentication, registry, email or cloud data when those sources are available.
6. Use KQL in a SOC Investigation Workflow
- Understand the alert: Identify the entity, time range, severity, product and rule that generated it.
- Confirm data availability: Determine which tables and connectors contain relevant telemetry.
- Start with a narrow query: Search for the user, device, IP address, hash or event.
- Expand the time range: Look for earlier access, persistence or related activity.
- Correlate entities: Connect identities, devices, processes, files and network destinations.
- Build a timeline: Arrange relevant events in chronological order.
- Validate business context: Determine whether the activity was authorised or expected.
- Document the conclusion: Record evidence, gaps, containment actions and escalation decisions.
7. Convert a Hunting Query into a Detection
A query that returns interesting results is not automatically ready to become an analytics rule.
Before creating a detection, confirm:
- The required log source is reliably collected
- The query targets meaningful behaviour
- The time window and frequency are appropriate
- The threshold is based on observed activity
- Likely false positives are documented
- Relevant entities are mapped
- The alert contains enough investigation context
- The SOC has a defined response procedure
- The query has been safely tested
| Detection field | Example |
|---|---|
| Name | Multiple failed logins followed by success |
| Data source | Windows Security events |
| Query period | Last 30 minutes |
| Threshold | Five or more failures followed by success |
| Possible false positives | User error, stale credentials or application misconfiguration |
| Entity mapping | Account, IP address and host |
| Analyst action | Validate the source, user and post-login activity |
8. KQL Query-Optimisation Tips
- Filter by time as early as possible
- Filter on specific event types before expensive operations
- Select only necessary output columns
- Avoid extremely broad searches across long retention periods
- Use case-sensitive operators where appropriate and understood
- Limit large arrays created by make_set or make_list
- Test each part of a complex query separately
- Inspect the schema instead of guessing field names
- Document why thresholds were selected
- Measure query performance using your actual environment
Less efficient starting pattern
SecurityEvent | search "test.user"
More focused pattern
SecurityEvent | where TimeGenerated > ago(24h) | where Account =~ "test.user" | project TimeGenerated, Computer, EventID, Activity, IpAddress
The focused query limits time, identifies the relevant column and returns only useful fields.
9. Common KQL Mistakes
Copying queries without checking the schema
A query from another environment may use tables or fields that do not exist in your workspace.
Using a very large time range
Broad searches can be slow and expensive. Start with the incident period, then expand deliberately.
Treating every match as malicious
Queries identify data matching conditions. They do not automatically prove intent or compromise.
Ignoring normal administrative activity
PowerShell, command-line tools, privileged logons and account changes can all be legitimate.
Using arbitrary thresholds
A threshold copied from another organisation may not fit your users, applications or authentication architecture.
Failing to normalise identities
One user may appear as a short name, domain-qualified account or UPN across different tables.
Building alerts without response instructions
Analysts must know what evidence to review and when to escalate or contain.
10. KQL Practice Exercises
Use only your authorised SOC home lab or approved training environment.
- Generate several failed logins and find them using Event ID 4625.
- Compare successful interactive and remote logon types.
- Create a test user and identify the corresponding account event.
- Add a test user to a lab security group and investigate the change.
- Run a harmless PowerShell command and trace its parent process.
- Identify the network connections made by a normal browser process.
- Build a one-hour timeline for one test user.
- Create a query that summarises failed logins by 15-minute intervals.
- Map three lab scenarios to relevant MITRE ATT&CK techniques.
- Document one query as a possible detection, including false positives.
Use the How to Build a SOC Home Lab: Complete Beginner Guide 2026 as the practical environment for these exercises.
11. KQL Interview Questions
What is KQL?
KQL is a read-only query language used to analyse large volumes of telemetry and time-series data. Security analysts use it in Microsoft Sentinel, Defender XDR and related platforms.
What does the where operator do?
It filters the input table so that only rows satisfying the specified condition continue to the next operator.
What does summarize do?
It aggregates rows using functions such as count, distinct count, minimum, maximum or collection-building functions.
Why is bin used with timestamps?
It groups timestamps into fixed intervals, allowing analysts to count or compare events across periods such as five or fifteen minutes.
What is the difference between contains and has?
Both search text, but token-based operators such as
has are designed around indexed terms. The best operator
depends on the intended matching behaviour and data.
What is join used for?
It combines rows from two tabular expressions using one or more shared columns, such as an account, device or IP address.
Why might a valid query return no results?
The time range may be wrong, the data connector may not be enabled, the required service may not be deployed, the selected table may contain no data or the filters may be too restrictive.
How would you investigate failed logins followed by success?
Identify the account, source, destination, failure reasons, logon types and timing; correlate the later successful login; then review the user’s subsequent process, network and account activity.
Frequently Asked Questions
Is KQL difficult for beginners?
The basics are approachable. Begin with one table and learn where, project, summarize, order by and bin. Add joins and multi-table timelines after becoming comfortable with simple queries.
Is KQL the same as SQL?
No. Both query data, but their syntax and common use cases differ. KQL uses a table-first, pipeline-based structure and is designed for analytics and telemetry exploration.
Where do SOC analysts use KQL?
KQL is used in Microsoft Sentinel, Microsoft Defender XDR, Azure Monitor Logs, Azure Data Explorer and other Microsoft data services.
Do I need Microsoft Sentinel to learn KQL?
Not necessarily, but Sentinel provides security-focused data and investigation scenarios. Use an authorised training environment and monitor any cloud costs.
Why does SecurityEvent not exist in my workspace?
The required Windows Security Events collection may not be configured, or your environment may store relevant data in another table. Review data connectors and the workspace schema.
Why do DeviceProcessEvents queries return no results?
This table depends on Microsoft Defender for Endpoint data. If the service is not deployed or integrated, the table may not be available or populated.
Can one KQL query prove an attack?
Usually not. A query returns events matching conditions. Analysts must validate context, related activity, business expectations and other evidence before reaching a conclusion.
How many KQL queries should a beginner learn?
Understanding ten well-selected queries is more valuable than memorising hundreds. Focus on authentication, accounts, processes, network activity and timelines.
Can I use these queries as production detection rules?
Treat them as learning and hunting templates. Production rules require schema validation, testing, tuning, entity mapping, threshold selection, false-positive analysis and response documentation.
Should I memorise KQL syntax for interviews?
Learn the important operators and be able to explain your investigation logic. Understanding how to find, correlate and interpret evidence is more valuable than memorising every function.
How can I practise KQL safely?
Use your own SOC home lab, an authorised training platform or a properly controlled Microsoft environment. Generate harmless administrative and authentication activity instead of using live malware.
How should I add KQL skills to my resume?
Describe tested work, such as developing KQL searches for authentication failures, account changes, process activity and incident timelines. Avoid claiming production experience when your work was completed in a personal lab.
Conclusion
KQL is one of the most useful technical skills for analysts working with Microsoft Sentinel and Defender XDR. It allows security teams to convert raw telemetry into investigation evidence, hunting results and detection logic.
Do not try to memorise all 25 queries. Begin with the searches most closely connected to entry-level SOC work:
- Failed and successful logins
- Accounts targeted by multiple failures
- New users and security-group changes
- PowerShell and process creation
- Network connections
- Suspicious IP and hash searches
- User and endpoint timelines
Practise each query in an authorised lab, understand the returned fields, generate safe test activity and document possible false positives. This approach develops practical investigation ability rather than simple syntax memorisation.
Build Practical KQL, SIEM and SOC Skills
Learn Windows security, Microsoft Sentinel, KQL, detection engineering and incident investigation through structured training, practical labs and mentor guidance.
WhatsApp or call: +91 98857 89887 | Email: trainings@thecyberseal.com
Career support may include resume guidance, interview preparation, LinkedIn optimisation and role-focused mentoring. Employment outcomes depend on individual skills, performance and market conditions.