This guide shows you how to run Sigma rules
on parsed security telemetry with the sigma operator. Use this pattern
to turn Windows Event Logs and other normalized records into Sigma sightings
without leaving the Tenzir pipeline.
The sigma operator transpiles rule YAML into a TQL expression. Semantically,
you can think of it as applying where to the input: non-matching
events are discarded, and matching events become tenzir.sigma records that
include the original event and the matched rule.
At a high level, the translation process looks as follows:
Detect encoded PowerShell in Windows Event Logs
Section titled “Detect encoded PowerShell in Windows Event Logs”Windows process creation events are a good fit for Sigma because many detections are field-level predicates over Event ID 4688. Start with a rule that matches PowerShell launched with an encoded command:
title: Encoded PowerShell Commandid: 7f01f6b8-9f1e-48f5-bab9-2d1f7040c6a1status: experimentaldescription: Detects Windows process creation events where PowerShell runs an encoded command.logsource: product: windows service: securitydetection: selection: System.EventID: 4688 EventData.NewProcessName|endswith: - '\powershell.exe' - '\pwsh.exe' EventData.CommandLine|contains: - ' -enc ' - ' -EncodedCommand ' - ' -encodedcommand ' condition: selectionfields: - System.Computer - EventData.SubjectUserName - EventData.NewProcessName - EventData.CommandLinelevel: highIf your collector sends native Windows Event Log XML, parse each event with
parse_winlog and then run the rule:
from_file "windows-security.xml" { read_delimited "</Event>\n", include_separator=true}this = data.parse_winlog()sigma "rules/windows/encoded-powershell.yml"{ event: { System: { Provider: { Name: "Microsoft-Windows-Security-Auditing", }, EventID: 4688, TimeCreated: { SystemTime: 2026-06-07T10:00:00Z, }, Channel: "Security", Computer: "WORKSTATION-17", }, EventData: { NewProcessName: "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", CommandLine: "powershell.exe -NoP -EncodedCommand SQBFAFgA", ParentProcessName: "C:\\Windows\\explorer.exe", SubjectUserName: "alice", }, }, rule: { title: "Encoded PowerShell Command", id: "7f01f6b8-9f1e-48f5-bab9-2d1f7040c6a1", status: "experimental", description: "Detects Windows process creation events where PowerShell runs an encoded command.", logsource: { product: "windows", service: "security", }, detection: { selection: { "System.EventID": 4688, "EventData.NewProcessName|endswith": [ "\\powershell.exe", "\\pwsh.exe", ], "EventData.CommandLine|contains": [ " -enc ", " -EncodedCommand ", " -encodedcommand ", ], }, condition: "selection", }, fields: [ "System.Computer", "EventData.SubjectUserName", "EventData.NewProcessName", "EventData.CommandLine", ], level: "high", },}For a live Windows Event Collector stream, keep the same parse-and-detect shape and change only the source:
accept_tcp "0.0.0.0:1514" { read_delimited "</Event>\n", include_separator=true}this = data.parse_winlog()sigma "/etc/tenzir/sigma/windows/", refresh_interval=30spublish "detections.sigma"The directory form lets you add or update rules without restarting the pipeline.
Every 30 seconds, Tenzir reloads the files in /etc/tenzir/sigma/windows/ and
uses the refreshed rule set for subsequent events.
See Windows Event Logs for collection patterns that deliver Windows Event Log XML to Tenzir.
Map parsed events to existing rule fields
Section titled “Map parsed events to existing rule fields”Many public Sigma rules use generic Windows field names such as EventID,
Image, CommandLine, ParentImage, and User. You can either edit the rule
to use System.* and EventData.* paths, or map the parsed Windows event to
those field names before sigma:
from_file "windows-security.xml" { read_delimited "</Event>\n", include_separator=true}this = data.parse_winlog()
EventID = System.EventIDImage = EventData.NewProcessNameCommandLine = EventData.CommandLineParentImage = EventData.ParentProcessNameUser = EventData.SubjectUserName
sigma "rules/windows/encoded-powershell-standard-fields.yml"{ event: { System: { Provider: { Name: "Microsoft-Windows-Security-Auditing", }, EventID: 4688, TimeCreated: { SystemTime: 2026-06-07T10:00:00Z, }, Channel: "Security", Computer: "WORKSTATION-17", }, EventData: { NewProcessName: "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", CommandLine: "powershell.exe -NoP -EncodedCommand SQBFAFgA", ParentProcessName: "C:\\Windows\\explorer.exe", SubjectUserName: "alice", }, EventID: 4688, Image: "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", CommandLine: "powershell.exe -NoP -EncodedCommand SQBFAFgA", ParentImage: "C:\\Windows\\explorer.exe", User: "alice", }, rule: { title: "Encoded PowerShell Command", logsource: { product: "windows", category: "process_creation", }, detection: { selection: { EventID: 4688, "Image|endswith": [ "\\powershell.exe", "\\pwsh.exe", ], "CommandLine|contains": [ " -enc ", " -EncodedCommand ", " -encodedcommand ", ], }, condition: "selection", }, level: "high", },}With that mapping, the corresponding rule can use the common field names:
title: Encoded PowerShell Commandlogsource: product: windows category: process_creationdetection: selection: EventID: 4688 Image|endswith: - '\powershell.exe' - '\pwsh.exe' CommandLine|contains: - ' -enc ' - ' -EncodedCommand ' - ' -encodedcommand ' condition: selectionlevel: highThis approach is useful when you import a rule set that already follows a field
taxonomy. The original Windows structure remains on the event, so analysts can
still inspect System and EventData after a match.
Transpile a process rule to OCSF TQL
Section titled “Transpile a process rule to OCSF TQL”You can also implement a Sigma detection in TQL directly, without going
through the sigma operator. This keeps your events in their canonical
shape — useful when you’ve normalized to a schema such as OCSF and don’t want
to rename fields back to Sigma’s Windows-style selectors only to satisfy a
rule.
A recent upstream Sigma process-creation rule,
proc_creation_win_print_dump_sensitive_files.yml (Sensitive File Dump Via Print.EXE, April 28, 2026), detects print.exe abuse for copying sensitive
Windows credential stores such as SAM, SECURITY, SYSTEM, and ntds.dit.
The relevant source YAML is:
title: Sensitive File Dump Via Print.EXEid: 2fcda7e2-8c57-4904-86ac-37fc3157e09dstatus: testdate: 2026-04-28logsource: category: process_creation product: windowsdetection: selection_img: - Image|endswith: '\print.exe' - OriginalFileName: 'Print.EXE' selection_cli: CommandLine|contains|windash: '/D' CommandLine|contains: - '\config\SAM' - '\config\SECURITY' - '\config\SYSTEM' - '\windows\ntds\ntds.dit' condition: all of selection_*falsepositives: - Unlikelylevel: highWhen your source already emits OCSF Process Activity events, translate the selectors to OCSF fields:
| Sigma selector | OCSF Process Activity field |
|---|---|
Image | process.path or process.name |
OriginalFileName | process.file.internal_name |
CommandLine | process.cmd_line |
| Host and user grouping | device.hostname and actor.user.name |
The following fixture contains two matching process launches and one benign
print.exe launch. The pipeline keeps the Sigma rule’s single-event semantics
and emits one detection per matching process event:
from { time: 2026-04-28T10:01:00Z, class_uid: 1007, activity_id: 1, device: {hostname: "WORKSTATION-17"}, actor: {user: {name: "alice"}}, process: { name: "print.exe", path: "C:\\Windows\\System32\\print.exe", file: {internal_name: "Print.EXE"}, cmd_line: "print.exe /D:C:\\Windows\\System32\\config\\SAM C:\\Temp\\sam.bak", },}, { time: 2026-04-28T10:02:00Z, class_uid: 1007, activity_id: 1, device: {hostname: "WORKSTATION-17"}, actor: {user: {name: "alice"}}, process: { name: "print.exe", path: "C:\\Windows\\System32\\print.exe", file: {internal_name: "Print.EXE"}, cmd_line: "print.exe /D:C:\\Windows\\System32\\config\\SYSTEM C:\\Temp\\system.bak", },}, { time: 2026-04-28T10:02:30Z, class_uid: 1007, activity_id: 1, device: {hostname: "WORKSTATION-17"}, actor: {user: {name: "alice"}}, process: { name: "print.exe", path: "C:\\Windows\\System32\\print.exe", file: {internal_name: "Print.EXE"}, cmd_line: "print.exe C:\\Users\\alice\\report.txt", },}
where class_uid == 1007 and activity_id == 1
// TQL does not support case-insensitive string matching functions yet. To avoid// the verbosity and overhead of calling `to_lower()` repeatedly (and to avoid// mutating the event by storing lowercase fields), we can use `match_regex`// with raw strings and the case-insensitive `(?i)` flag.where process.path.match_regex(r"(?i)\\print\.exe$") \ or process.name.match_regex(r"(?i)^print\.exe$") \ or process.file.internal_name.match_regex(r"(?i)^print\.exe$")
where process.cmd_line.match_regex(r"(?i)[/-]d") and process.cmd_line.match_regex( r"(?i)\\config\\(sam|security|system)|\\windows\\ntds\\ntds\.dit")
select time, host=device.hostname, user=actor.user.name, command=process.cmd_line, rule="Sensitive File Dump Via Print.EXE", level="high"{ time: 2026-04-28T10:01:00Z, host: "WORKSTATION-17", user: "alice", command: "print.exe /D:C:\\Windows\\System32\\config\\SAM C:\\Temp\\sam.bak", rule: "Sensitive File Dump Via Print.EXE", level: "high",}{ time: 2026-04-28T10:02:00Z, host: "WORKSTATION-17", user: "alice", command: "print.exe /D:C:\\Windows\\System32\\config\\SYSTEM C:\\Temp\\system.bak", rule: "Sensitive File Dump Via Print.EXE", level: "high",}If you package this predicate as operators/detections/print_sensitive_dump.tql
in a package named windows_threats, callers can use the operator
windows_threats::detections::print_sensitive_dump and add correlation
separately. For example, use window after the UDO when you want one alert for
repeated matches on the same host and user:
from_file "ocsf-process-events.json" { read_ndjson}windows_threats::detections::print_sensitive_dumpwindow size=5min, on=time { summarize host, user, rule, level, match_count=count(), commands=distinct(command) where match_count > 1 window_start = $window.start window_end = $window.end}For the two detection records from the earlier fixture, the windowed pipeline emits one correlated result:
{ host: "WORKSTATION-17", user: "alice", rule: "Sensitive File Dump Via Print.EXE", level: "high", match_count: 2, commands: [ "print.exe /D:C:\\Windows\\System32\\config\\SAM C:\\Temp\\sam.bak", "print.exe /D:C:\\Windows\\System32\\config\\SYSTEM C:\\Temp\\system.bak", ], window_start: 2026-04-28T10:00:00Z, window_end: 2026-04-28T10:05:00Z,}