Skip to content
SOC FluentSpeak SIEM and EDR

Microsoft Sentinel and Defender XDRvsSplunk

KQL vs SPL

KQL (Microsoft Sentinel and Defender) and SPL (Splunk) are both pipe-based languages for searching security logs. They work the same way. You start with the data, then filter, shape and count it one step at a time. The differences are mostly the names of things, the case rules and where the time range is set.

Side by side

WhatKQLSPL
Used inMicrosoft Sentinel and Defender XDRSplunk Enterprise, Splunk Cloud and Enterprise Security
A query starts withA table, like SecurityEventA search, like index=wineventlog
Filter rowswhere EventID == 4625EventCode=4625 in the search, or where
Pick columnsprojecttable or fields
Count and groupsummarize count() by Accountstats count by user
Sortsort by Failures, descending by defaultsort -Failures, the minus means descending
Keep the top rowstop 10 by Failuressort -Failures then head 10
Add a columnextendeval
Pull text out with regexextract() or parserex
Time rangeThe time picker, or in the query with ago()The time picker, or earliest= in the search
Matching text== is case-sensitive, =~ isn’tSearch terms ignore case, where and eval don’t
Field namesCase-sensitiveCase-sensitive

Same question, both languages

Which accounts failed to log on most in the last day?
KQL
SecurityEvent
| where TimeGenerated > ago(1d)
| where EventID == 4625
| summarize Failures = count() by TargetAccount
| top 10 by Failures
SPL
index=wineventlog EventCode=4625 earliest=-1d
| stats count AS Failures BY user
| sort -Failures
| head 10
Did Word, Excel or Outlook start PowerShell this week?
KQL
DeviceProcessEvents
| where Timestamp > ago(7d)
| where InitiatingProcessFileName in~ ("winword.exe", "excel.exe", "outlook.exe")
| where FileName =~ "powershell.exe"
| project Timestamp, DeviceName, AccountName, ProcessCommandLine
SPL
index=sysmon EventCode=1 earliest=-7d Image="*\\powershell.exe"
  (ParentImage="*\\winword.exe" OR ParentImage="*\\excel.exe" OR ParentImage="*\\outlook.exe")
| table _time host User CommandLine

Index and field names in Splunk depend on how your data is set up. These use the common Windows and Sysmon add-ons.

What catches people out when switching

  • sort in KQL is descending unless you say asc. In SPL sort Failures is ascending, and you add a minus for descending.
  • summarize count() names the column count_ in KQL. In SPL stats count names it count.
  • SPL’s sort stops at 10,000 rows unless you write sort 0 -Failures.
  • Searching for powershell in SPL matches any case. In KQL == doesn’t, so use =~ or has.
  • Field names are case-sensitive in both, so eventcode won’t find EventCode.
  • In both, the time picker sets the range unless the query sets its own. Check which one is in charge before trusting an empty result.

Practise both on the same exercise

SOC Fluent launches with KQL, and SPL is coming soon. Every exercise works in each language, so you can solve the same exercise in both and compare.

Free to join. Students get 50% off at launch.