Command History with Process Tree
Correlates CommandHistory events with ProcessRollup2 to show PowerShell command history together with the execution chain (parent → child process with PID). Provides context on how each PowerShell session was launched.
#event_simpleName=/^(CommandHistory|ProcessRollup2)$/
event_platform=Win
| selfJoinFilter(
field=[aid, TargetProcessId],
where=[
{ #event_simpleName=ProcessRollup2 },
{ #event_simpleName=CommandHistory }
]
)
| case {
#event_simpleName=CommandHistory
| CommandHistory=*
| splitString(
field=CommandHistory,
by="¶",
as=CommandHistorySplit
)
| concatArray(
CommandHistorySplit,
separator="\n",
as=CommandHistoryClean
);
#event_simpleName=ProcessRollup2
| ImageFileName=/\\(?<ChildBaseFileName>[^\\]+)$/
| ExecutionChain := format(
format="%s → %s (PID: %s)",
field=[ParentBaseFileName, ChildBaseFileName, RawProcessId]
);
}
| groupBy([aid, ComputerName, TargetProcessId], function=[
selectLast(ExecutionChain),
selectLast(CommandHistoryClean)
], limit=max)
| CommandHistoryClean=*How It Works
- Collects two event types (Windows only): - CommandHistory: the console history of a PowerShell process, written when the process exits - ProcessRollup2: the process execution event, including parent process information
- Correlates via selfJoinFilter: - Joins on aid + TargetProcessId - Keeps only processes for which both events are present
- Processes each event type:
- CommandHistory: splits the multi-command history field (separator: ¶) and reassembles it with newlines into CommandHistoryClean
- ProcessRollup2: builds an ExecutionChain string, e.g.
cmd.exe → powershell.exe (PID: 1234) - Groups results: - One row per PowerShell process (aid + TargetProcessId) - Each row shows the host, the execution chain, and the full cleaned command history
Required Telemetry
Falcon sensor endpoint telemetry on Windows hosts. CommandHistory is emitted at process termination, so long-running PowerShell consoles only appear after they close.
Interpreting Results
The ExecutionChain shows what spawned the PowerShell session. Unusual parents (Office applications, browsers, java.exe, wscript.exe) combined with suspicious commands in the history are the main hunting signal.
False Positives and Tuning
Most results will be legitimate administrator and automation activity. To reduce noise:
- Filter on suspicious parents, e.g. add ParentBaseFileName=/^(winword|excel|outlook|mshta|wscript)\.exe$/i to the ProcessRollup2 case
- Search the history for keywords, e.g. append | CommandHistoryClean=/downloadstring|invoke-webrequest|frombase64string/i
- Exclude known management hosts or service accounts as needed
