A process-name alert is not a detection strategy

PowerShell runs legitimately across most Windows estates. Alerting every time powershell.exe starts produces noise; treating the absence of that filename as safety creates a blind spot.

Attackers can execute PowerShell through alternate hosts or load System.Management.Automation into another process. Even when the standard executable appears, the useful evidence is rarely the name alone.

Hunting model

Ask three questions together: what did the script do, who launched it, and what did the process communicate with afterward?

Read the command after the disguise

Obfuscation is a clue, not a verdict. Common patterns include encoded commands, fragmented strings, execution-policy bypasses, hidden windows, and download-and-execute primitives.

  • -EncodedCommand, shortened variants, or calls to FromBase64String.
  • Combinations such as Bypass, NoProfile, NonInteractive, and WindowStyle Hidden.
  • String construction intended to hide Invoke-Expression or other sensitive terms.
  • Invoke-WebRequest, Net.WebClient, or Start-BitsTransfer followed by execution.
Illustrative Sigma rule
title: Suspicious PowerShell Encoding or Download Primitives
logsource:
  category: process_creation
  product: windows
detection:
  image:
    Image|endswith:
      - '\powershell.exe'
      - '\pwsh.exe'
  content:
    CommandLine|contains:
      - '-EncodedCommand'
      - 'FromBase64String'
      - 'DownloadString'
      - 'Invoke-WebRequest'
  condition: image and content
level: high

Keyword rules catch low-effort activity, but they are easy to evade. Script Block Logging records processed script-block content and produces Event ID 4104, giving defenders visibility beyond the original command line.

Logging caution

Script logging can capture secrets handled by legitimate automation. Protect access to the logs, consider Protected Event Logging, control retention, and test the volume before broad deployment.

Inspect the caller and the caller’s caller

Process ancestry supplies the execution story. A familiar PowerShell command launched by a trusted management agent has different meaning from the same command launched through a document, browser, or script host.

Parent or ancestorInvestigation question
winword.exe / excel.exe / outlook.exeDid a document, attachment, macro, or link begin the chain?
mshta.exe / wscript.exe / cscript.exeIs a script host staging or launching the payload?
wmiprvse.exeDoes the activity match approved remote administration or possible lateral movement?
rundll32.exe / regsvr32.exeIs a signed Windows binary being used to proxy execution?
browser → shell → PowerShellDid a download, fake update, or copy-and-paste instruction trigger execution?
PowerShell → PowerShellIs this expected orchestration or a multi-stage loader?

Go beyond the immediate parent. A chain such as browser → script host → command shell → PowerShell often explains intent more clearly than any single process.

Correlate execution with outbound activity

PowerShell often acts as a download, discovery, or launch stage. Network telemetry can reveal what happened after execution: a raw-IP connection, a first-seen domain, repeated beacon-like intervals, or a download primitive paired with an actual connection.

Microsoft Defender XDR · starting correlation
let PowerShellProcesses = DeviceProcessEvents
| where FileName in~ ("powershell.exe", "pwsh.exe")
| where isnotempty(ProcessUniqueId)
| project DeviceId, ProcessUniqueId, ProcessCommandLine,
          ProcessStart = Timestamp;
DeviceNetworkEvents
| where InitiatingProcessFileName in~ ("powershell.exe", "pwsh.exe")
| where RemoteIPType == "Public"
| join kind=inner PowerShellProcesses on DeviceId
| where InitiatingProcessUniqueId == ProcessUniqueId
| project Timestamp, DeviceName, RemoteIP, RemoteUrl,
          RemotePort, ProcessCommandLine, ProcessStart

Use stable process-instance identifiers where available. Windows reuses process IDs, so joining only on device and PID can accidentally combine unrelated activity from different times.

  • Compare the destination with domain age, reputation, hosting provider, and prevalence in your environment.
  • Confirm whether the connection occurred within the lifetime of the process and whether a child process continued the activity.
  • Review DNS, proxy, firewall, and endpoint telemetry together; a missing event in one source is not proof that no connection occurred.
  • Validate whether the same script, signer, management tool, or destination is common across similar devices.

Combine weak signals into a strong case

Encoded content, a hidden window, or an outbound HTTPS connection may each be legitimate in isolation. The useful signal is the combination and the degree to which it departs from the host, user, and management baseline.

Example signalIllustrative weight
Encoded or heavily obfuscated command+3
Script block contains download-and-execute behaviour+3
Office, browser, or script-host ancestry+3
Unexpected nested PowerShell process+2
Public raw-IP connection shortly after launch+2
Multiple stealth flags together+2
Repeated low-variance outbound timing+3

Treat the weights as a design example, not a universal threshold. Test them against known-good administration, tune by device role, and promote combinations that consistently separate malicious behaviour from routine automation.

Bottom line

Collect script content, preserve ancestry, correlate network activity, and tune against the local baseline. Durable detection is a chain of evidence, not a filename.