Help us improve
Share bugs, ideas, or general feedback.
From sentinelone
Executes threat hunting queries using SentinelOne PowerQuery on Singularity Data Lake, explains pipeline syntax, manages time ranges with get_timestamp_range and iso_to_unix_timestamp, analyzes results.
npx claudepluginhub wyre-technology/msp-claude-plugins --plugin sentineloneHow this skill is triggered — by the user, by Claude, or both
Slash command
/sentinelone:threat-huntingThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
PowerQuery is SentinelOne's query language for searching the Singularity Data Lake -- the centralized telemetry repository containing process events, network connections, file operations, registry changes, and other security-relevant data from all managed endpoints and cloud workloads. For MSPs, PowerQuery is the primary tool for deep forensic analysis, threat hunting, and incident investigatio...
Guides use of SentinelOne Purple AI for natural language cybersecurity investigations, threat hunting, behavioral anomaly analysis, MITRE ATT&CK TTP mapping, and PowerQuery generation via purple_ai tool.
Conducts threat hunts on Clawdstrike events: timelines, filtered queries, pattern correlations, IOC checks, MITRE ATT&CK mapping, and incident reports.
Develop, optimize, and troubleshoot CrowdStrike LogScale (Humio) security detection queries using CQL syntax. Use when writing LogScale queries, building security detections, creating threat hunting rules, fixing CQL syntax errors, working with CrowdStrike EDR/Falcon security monitoring, or building behavioral rules with the correlate() function. Handles case statements, risk categorization, multi-event correlation, investigation playbooks, and actionable security outputs.
Share bugs, ideas, or general feedback.
PowerQuery is SentinelOne's query language for searching the Singularity Data Lake -- the centralized telemetry repository containing process events, network connections, file operations, registry changes, and other security-relevant data from all managed endpoints and cloud workloads. For MSPs, PowerQuery is the primary tool for deep forensic analysis, threat hunting, and incident investigation across client environments.
IMPORTANT: PowerQuery is a Scalyr-based pipeline query language. It is NOT Splunk SPL, SQL, KQL (Kusto), or Elasticsearch Query DSL. The syntax is fundamentally different. The recommended approach is to use the
purple_aitool to generate PowerQuery strings from natural language descriptions, then execute them with thepowerquerytool.
| Tool | Description | Key Parameters |
|---|---|---|
powerquery | Execute a PowerQuery against the Singularity Data Lake | query (required), fromDate, toDate |
get_timestamp_range | Get the available time range for PowerQuery data | None |
iso_to_unix_timestamp | Convert ISO 8601 timestamp to Unix epoch milliseconds | timestamp (required) |
Call powerquery with a query string and optional time range:
Default time range: Last 24 hours if not specified.
Example: Find PowerShell network connections:
powerquery with query="EventType = \"IP Connect\" AND SrcProcName = \"powershell.exe\" | columns EndpointName, SrcProcCmdLine, DstIP, DstPort | limit 100"Example: With custom time range:
powerquery with query="EventType = \"Process Creation\" AND TgtProcName = \"mimikatz.exe\" | limit 50", fromDate="2026-02-23T00:00:00Z", toDate="2026-02-24T00:00:00Z"Call get_timestamp_range to determine how far back the Data Lake has data. Returns the earliest and latest available timestamps.
Call iso_to_unix_timestamp to convert ISO 8601 timestamps to Unix epoch milliseconds, which is required by some query parameters.
PowerQuery uses a pipeline model with filters, columns, sorting, and aggregation:
<filter expression>
| columns <field1>, <field2>, ...
| sort -<field>
| limit <n>
| group <field> calculate count() as cnt
Filters use field operator value syntax:
| Operator | Description | Example |
|---|---|---|
= | Equals | EventType = "Process Creation" |
!= | Not equals | SrcProcName != "explorer.exe" |
contains | Substring match | TgtProcCmdLine contains "powershell" |
In | Match list | DstPort In (80, 443, 8080) |
NOT In | Exclude list | NOT DstIP In ("10.0.0.0/8") |
AND | Logical AND | EventType = "IP Connect" AND DstPort = 4444 |
OR | Logical OR | SrcProcName = "cmd.exe" OR SrcProcName = "powershell.exe" |
| Operator | Description | Example |
|---|---|---|
columns | Select specific fields | | columns EndpointName, SrcProcName, DstIP |
sort | Sort results (prefix - for descending) | | sort -EventTime |
limit | Limit result count (max 100) | | limit 100 |
group | Aggregate data | | group EndpointName calculate count() as cnt |
filter | Post-pipeline filter | | filter cnt > 10 |
| Event Type | Description |
|---|---|
Process Creation | New process started |
Process Exit | Process terminated |
IP Connect | Network connection established |
IP Listen | Port opened for listening |
File Creation | File created |
File Modification | File modified |
File Deletion | File deleted |
Registry Key Creation | Registry key created |
Registry Value Modified | Registry value changed |
DNS | DNS query |
Login | User login event |
Logout | User logout event |
Module Load | DLL or shared library loaded |
URL | URL accessed |
| Field | Description |
|---|---|
EndpointName | Hostname of the endpoint |
SiteName | SentinelOne site (MSP client) |
EventTime | Event timestamp |
EventType | Type of event |
SrcProcName | Source (parent) process name |
SrcProcCmdLine | Source process command line |
SrcProcPid | Source process ID |
TgtProcName | Target (child) process name |
TgtProcCmdLine | Target process command line |
TgtProcPid | Target process ID |
DstIP | Destination IP address |
DstPort | Destination port |
SrcIP | Source IP address |
SrcPort | Source port |
NetConnStatus | Network connection status |
TgtFileName | Target file name/path |
TgtFileHashSha256 | Target file SHA256 hash |
RegistryKeyPath | Registry key path |
RegistryValueName | Registry value name |
DNSRequest | DNS query domain |
URL | Accessed URL |
User | User account |
| Constraint | Value |
|---|---|
| Maximum rows returned | 100 |
| Default time range | Last 24 hours |
| Query timeout | 5 minutes |
| Empty results | Valid (no matching data, not an error) |
EventType = "Process Creation" AND
(TgtProcName = "psexec.exe" OR TgtProcName = "psexesvc.exe" OR
TgtProcCmdLine contains "wmic" AND TgtProcCmdLine contains "/node:")
| columns EndpointName, SiteName, SrcProcName, TgtProcName, TgtProcCmdLine, EventTime
| sort -EventTime
| limit 100
EventType = "Process Creation" AND
TgtProcCmdLine contains "lsass" AND
SrcProcName != "svchost.exe" AND SrcProcName != "csrss.exe"
| columns EndpointName, SiteName, SrcProcName, TgtProcName, TgtProcCmdLine, User, EventTime
| sort -EventTime
| limit 100
EventType = "Process Creation" AND
TgtProcName = "schtasks.exe" AND TgtProcCmdLine contains "/create"
| columns EndpointName, SiteName, SrcProcName, TgtProcCmdLine, User, EventTime
| sort -EventTime
| limit 100
EventType = "IP Connect" AND NetConnStatus = "SUCCESS" AND
NOT DstIP In ("10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16") AND
DstPort NOT In (80, 443)
| group DstIP, SrcProcName, EndpointName calculate count() as connections
| filter connections > 50
| sort -connections
| limit 100
EventType = "Process Creation" AND
(TgtProcName In ("7z.exe", "rar.exe", "zip.exe", "tar.exe") OR
TgtProcCmdLine contains "Compress-Archive")
| columns EndpointName, SiteName, SrcProcName, TgtProcCmdLine, User, EventTime
| sort -EventTime
| limit 100
EventType = "Process Creation" AND
TgtProcName In ("certutil.exe", "mshta.exe", "regsvr32.exe", "rundll32.exe",
"wscript.exe", "cscript.exe", "bitsadmin.exe") AND
(TgtProcCmdLine contains "http" OR TgtProcCmdLine contains "ftp" OR
TgtProcCmdLine contains "/decode" OR TgtProcCmdLine contains "script:")
| columns EndpointName, SiteName, SrcProcName, TgtProcName, TgtProcCmdLine, EventTime
| sort -EventTime
| limit 100
EventType = "DNS" AND
DNSRequest contains "." AND
NOT DNSRequest In ("*.microsoft.com", "*.windows.com", "*.windowsupdate.com",
"*.office.com", "*.sentinelone.net")
| group DNSRequest calculate count() as queries
| filter queries > 100
| sort -queries
| limit 100
EventType = "Process Creation" AND
SrcProcName In ("winword.exe", "excel.exe", "powerpnt.exe") AND
TgtProcName In ("powershell.exe", "cmd.exe", "wscript.exe", "cscript.exe", "mshta.exe")
| columns EndpointName, SiteName, SrcProcName, TgtProcName, TgtProcCmdLine, User, EventTime
| sort -EventTime
| limit 100
The recommended threat hunting workflow is:
purple_ai with a natural language description of what you want to findget_timestamp_range to verify data availabilitypowerquery with the generated query stringPowerQuery Result:
{
"rows": [
{
"EndpointName": "ACME-WS-042",
"SrcProcName": "winword.exe",
"TgtProcName": "powershell.exe",
"TgtProcCmdLine": "powershell.exe -enc aQBlAHgA...",
"EventTime": "2026-02-24T08:12:34.000Z"
},
{
"EndpointName": "ACME-WS-015",
"SrcProcName": "excel.exe",
"TgtProcName": "cmd.exe",
"TgtProcCmdLine": "cmd.exe /c whoami && net user",
"EventTime": "2026-02-24T07:45:12.000Z"
}
],
"totalRows": 2
}
Empty Result (Valid):
{
"rows": [],
"totalRows": 0
}
Empty results are valid and common in threat hunting. No results means no matching telemetry was found -- which is often a positive finding.
| Error | Cause | Resolution |
|---|---|---|
| Syntax error | Invalid PowerQuery syntax | Use purple_ai to generate correct syntax |
| Timeout | Query too broad or time range too large | Narrow the time range or add more filters |
| No data available | Time range outside Data Lake retention | Call get_timestamp_range to check availability |
| Authentication error | Invalid token | Verify Service User token is Account or Site level |
| Rate limited | Too many queries | Wait before retrying |
SrcProcName = "powershell.exe"In (capital I) for list matches: DstPort In (80, 443)NOT before conditions for negation: NOT DstIP In ("10.0.0.0/8")| on a new line or after a space| limit 100 to stay within the row limitSiteName = "Client Name" to scope hunts to specific clients