CrowdStrike Falcon uses LogScale — formerly Humio — as its underlying query and search engine. The query language is fast and powerful but has a different structure from Splunk SPL or Sentinel KQL, and the documentation assumes you already know what you're doing. This guide covers the language from the ground up, the way you'd need to know it to build real detections in a production SOC environment.

Weekly Intelligence Pack · $14.99/mo
New CrowdStrike detection rule every few weeks
LogScale queries with real production tuning — field names, false positive suppression, and the investigation steps that close the alert. Rotating across CrowdStrike, Sentinel, and Splunk.
Join — $14.99/mo →

How LogScale Queries Work

LogScale queries are pipeline-based. Each step in the pipeline takes the output of the previous step and transforms it. The pipe character `|` separates steps. This is similar to Splunk's pipe syntax, but LogScale's filter functions work differently and the field naming conventions are specific to CrowdStrike's event schema.

The basic structure is: filter events → extract or transform fields → aggregate or format output.

LogScale — basic pipeline structure
// Step 1: filter by event type
#event_simpleName=ProcessRollup2

// Step 2: filter by field value
FileName="powershell.exe"

// Step 3: transform — extract fields, rename, compute
| rename(field=ComputerName, as=Hostname)

// Step 4: aggregate
| groupBy([Hostname, UserName], function=count())

// Step 5: sort output
| sort(_count, order=desc)

The CrowdStrike Event Schema

CrowdStrike events in LogScale follow a consistent naming convention. Understanding this is the first step to writing effective queries — if you use the wrong field name, the query returns nothing without an error, which makes debugging frustrating.

Core fields present on every event

FieldDescriptionExample
#event_simpleNameThe event type — most important filter fieldProcessRollup2, DnsRequest, NetworkConnectIP4
@timestampEvent timestamp in millisecondsUsed with | timechart or time range filters
ComputerNameHostname of the endpointWORKSTATION-001
UserNameUsername associated with the eventDOMAIN\jsmith
aidAgent ID — unique per sensor installUsed to correlate events across types
cidCustomer ID — your tenant identifierSame across all your events

Process event fields (ProcessRollup2)

FieldDescription
FileNameName of the process binary (e.g. powershell.exe)
ImageFileNameFull path to the process binary
CommandLineFull command line including arguments
ParentBaseFileNameName of the parent process binary
ParentProcessIdPID of the parent process
ProcessIdPID of this process
SHA256HashDataSHA256 hash of the binary
UserSidSID of the user running the process
Field name gotcha

CrowdStrike field names are case-sensitive. `FileName` works. `filename` returns nothing. `FILENAME` returns nothing. This catches analysts coming from Splunk or KQL where field matching is often case-insensitive. Always check the exact field name in a sample event before building a detection.

Filter Syntax

Exact match

LogScale — exact field match
// String exact match — case sensitive by default
FileName="powershell.exe"

// Case-insensitive match using regex flag
FileName=/powershell\.exe/i

// Numeric match
ProcessId=1234

// NOT match
FileName!="explorer.exe"

IN list matching

LogScale — IN operator for multiple values
// Match any of a list of values
FileName IN ["powershell.exe", "pwsh.exe", "cmd.exe"]

// Case-insensitive IN
ParentBaseFileName IN~ ["winword.exe", "excel.exe", "outlook.exe"]

// NOT IN — exclude a list
FileName NOT IN ["svchost.exe", "lsass.exe", "csrss.exe"]

Wildcard and regex matching

LogScale — wildcard and regex
// Wildcard — * matches any characters
ImageFileName=*\powershell.exe

// Regex — wrap in forward slashes
CommandLine=/(-enc|-encodedcommand)/i

// Regex with anchors
ImageFileName=/\/powershell\.exe$/i

// Contains substring (use regex for this)
CommandLine=/http/i

Field existence and null checks

LogScale — field existence checks
// Field exists and has a value
CommandLine=*

// Field does not exist or is empty
CommandLine!=*

// Using test() for complex conditions
| test(ProcessId > 1000)

Aggregation Functions

Aggregations summarize event data across a time window or group. These are what turn raw event streams into detection signals.

LogScale — core aggregation functions
// Count events, grouped by fields
| groupBy([ComputerName, UserName], function=count())

// Count with custom output field name
| groupBy([ComputerName],
    function=count(as=EventCount))

// Count distinct values
| groupBy([UserName],
    function=count(field=ComputerName, distinct=true, as=UniqueHosts))

// Collect values into an array
| groupBy([UserName],
    function=collect([ComputerName, FileName]))

// Multiple aggregations in one groupBy
| groupBy([ComputerName], function=[
    count(as=TotalEvents),
    count(field=UserName, distinct=true, as=UniqueUsers),
    max(field=@timestamp, as=LastSeen)
  ])

Time Range and Time Series

LogScale — time functions
// Time chart — count events per time bucket
| timechart(span=1h, function=count())

// Filter to specific time window in query
| where(@timestamp > now() - 1h)

// Time since event (in milliseconds)
| eval(age = now() - @timestamp)
| eval(ageMinutes = age / 60000)

Regex Extraction

Regex extraction pulls structured data out of unstructured fields like command lines. This is essential for parsing encoded commands, URLs, file paths, and other variable-length strings.

LogScale — regex field extraction
// Extract encoded command from PowerShell command line
| regex(
    "(?i)-(?:enc|encodedcommand)\s+(?P<EncodedPayload>[A-Za-z0-9+/=]{20,})",
    field=CommandLine
  )

// Extract domain from DNS request
| regex(
    "(?P<TLD>[^.]+\.[^.]+)$",
    field=DomainName
  )

// Extract username from UPN format
| regex(
    "(?P<Username>[^@]+)@",
    field=UserPrincipalName
  )

// Named capture groups become new fields automatically

Joins and Lookups

LogScale — join two event streams
// Find processes that also made network connections
#event_simpleName=ProcessRollup2
FileName="powershell.exe"
| join(
    query={
      #event_simpleName=NetworkConnectIP4
      | groupBy([ContextProcessId],
          function=collect([RemoteAddressIP4, RemotePort]))
    },
    field=ProcessId,
    include=[RemoteAddressIP4, RemotePort]
  )

Production Detection Patterns

Suspicious process spawning

LogScale — Office app spawning scripting engine
#event_simpleName=ProcessRollup2
ParentBaseFileName IN~ [
  "winword.exe", "excel.exe",
  "outlook.exe", "powerpnt.exe"
]
FileName IN~ [
  "powershell.exe", "cmd.exe",
  "wscript.exe", "cscript.exe",
  "mshta.exe", "rundll32.exe"
]
| table([@timestamp, ComputerName, UserName,
    ParentBaseFileName, FileName, CommandLine])
| sort(@timestamp, order=desc)

Lateral movement — NTLM authentication sweep

LogScale — NTLM lateral movement detection
#event_simpleName=UserLogon
LogonType=3
AuthenticationPackage="NTLM"
// Exclude machine accounts
UserName!=*$
| groupBy([UserName, RemoteIP],
    function=[
      count(as=AuthCount),
      count(field=ComputerName, distinct=true, as=TargetHosts),
      collect([ComputerName])
    ])
| where(TargetHosts >= 3)
| sort(TargetHosts, order=desc)

Data exfiltration — large DNS query volume

LogScale — DNS exfiltration pattern
#event_simpleName=DnsRequest
// Filter out common benign domains
DomainName!=*.microsoft.com
DomainName!=*.windows.com
DomainName!=*.windowsupdate.com
| groupBy([ComputerName, DomainName],
    function=count(as=QueryCount))
| where(QueryCount > 100)
// High query volume to single domain = possible exfil via DNS
| sort(QueryCount, order=desc)

Common Mistakes in LogScale Queries

Weekly Intelligence Pack
Production CrowdStrike detection rules in the rotation

Every issue that covers CrowdStrike includes a complete LogScale query — field names verified, false positive suppression tuned, investigation steps included, MITRE mapping attached. Rotating across CrowdStrike, Sentinel, and Splunk weekly.

Join — $14.99/mo See a Sample Issue
Founding member pricing locked for life · 30-day money back