PowerShell threat hunting one-liners are the equivalent of a paramedic's pocket card — not where you do the bulk of the work, but exactly what you reach for when something looks wrong and you need an answer right now. The collection below is the one we paste from memory during the first five minutes of looking at a possibly-compromised Windows host. Everything here is read-only and intended for authorised triage on systems you administer.
Key Takeaways
- One-liners are for quick orientation, not continuous monitoring. For that, use a SIEM or EDR product such as Microsoft Defender for Endpoint.
- The most useful triage signals are processes (parent-child + command line), services running from unusual paths, autorun registry entries, and outbound network connections.
Get-CimInstancebeatsGet-Processfor triage because it exposesParentProcessId,CommandLine, and creation timestamps.-ErrorAction SilentlyContinueis essential when walking the filesystem or registry as a non-elevated user; without it, the output is buried in access-denied errors.- Pipe anything interesting to
Export-Csv -Encoding UTF8BOMto share results with another analyst.
Environment
- Windows 10/11 or Windows Server 2019/2022.
- Windows PowerShell 5.1 or PowerShell 7.4 — every snippet works on both unless flagged.
- Local administrator rights. Several queries silently truncate output without elevation.
- Authorised access to the host. These commands are read-only but should still only run with permission.
The One-Liners
Top CPU consumers right now
Get-Process | Sort-Object CPU -Descending | Select-Object -First 10 ProcessName, Id, CPU, @{N='MB';E={[math]::Round($_.WorkingSet64/1MB,1)}}
Quick orientation. Anything sitting at 80–100% CPU that you do not recognise is your first lead — particularly common with coin miners and unpacked loaders.
Processes with their parent and command line
$p = Get-CimInstance Win32_Process; $p | Select-Object ProcessId,Name,CommandLine,@{N='Parent';E={($p|? ProcessId -eq $_.ParentProcessId).Name}} | Sort-Object Parent,Name
Living-off-the-land abuse hides in this view. Look for Office applications, outlook.exe, or browser processes spawning cmd.exe, powershell.exe, wscript.exe, mshta.exe, or regsvr32.exe.
PowerShell command lines with suspicious arguments
Get-CimInstance Win32_Process -Filter "Name='powershell.exe' OR Name='pwsh.exe'" | Where-Object { $_.CommandLine -match '(-enc|-encodedcommand|frombase64string|downloadstring|downloadfile|-w hidden|-windowstyle hidden)' } | Select-Object ProcessId,ParentProcessId,CommandLine
Catches the classic encoded-payload patterns. Expect false positives from internal deployment tooling; build a known-good list before alerting.
Established connections to non-RFC1918 destinations
Get-NetTCPConnection -State Established | Where-Object { $_.RemoteAddress -notmatch '^10\.|^172\.(1[6-9]|2[0-9]|3[01])\.|^192\.168\.|^127\.|^::1' } | Select-Object LocalPort,RemoteAddress,RemotePort,@{N='Process';E={(Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue).Name}}
Filters out RFC 1918 ranges and loopback. Remaining rows are processes talking out to the public internet — handy for spotting unusual C2-style traffic.
Services running from temporary or user-writable paths
Get-CimInstance Win32_Service | Where-Object { $_.PathName -match 'temp|appdata|programdata|users\\public' } | Select-Object Name,DisplayName,PathName,StartName,State
Legitimate services almost never live in user-writable paths. Anything matching here deserves a closer look at the binary signature.
Services set to auto-start but currently stopped
Get-Service | Where-Object { $_.StartType -eq 'Automatic' -and $_.Status -eq 'Stopped' } | Select-Object Name,DisplayName,Status,StartType
Sometimes attackers disable defensive services (Defender, Windows Update, BITS) without unsetting auto-start. Compare against a known-good baseline.
Autorun entries from the four classic Run keys
'HKLM:\Software\Microsoft\Windows\CurrentVersion\Run','HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce','HKCU:\Software\Microsoft\Windows\CurrentVersion\Run','HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce' | ForEach-Object { Get-ItemProperty $_ -ErrorAction SilentlyContinue | Select-Object PSPath,* -ExcludeProperty PS* }
The simplest persistence anchor. For broader coverage use Sysinternals Autoruns; this one-liner catches the most common locations.
Recently created executables outside Program Files
Get-ChildItem -Path C:\ -Include *.exe,*.dll,*.ps1,*.bat,*.cmd -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.CreationTime -gt (Get-Date).AddHours(-24) -and $_.FullName -notmatch 'Program Files|Windows\\(System32|SysWOW64|WinSxS|servicing|assembly)' } | Select-Object FullName,CreationTime,Length
Filesystem-level new-arrival check. Tune the time window and exclusion list to match what your environment legitimately drops.
Scheduled tasks created in the last seven days
Get-ScheduledTask | Get-ScheduledTaskInfo | Where-Object { $_.LastRunTime -gt (Get-Date).AddDays(-7) -or $_.NextRunTime -gt (Get-Date) } | Select-Object TaskName,LastRunTime,NextRunTime,LastTaskResult
Scheduled tasks are a top persistence mechanism. Cross-reference with the dedicated detection post linked below for deeper analysis.
Local admins (including nested group members)
Get-LocalGroupMember -Group 'Administrators' | Select-Object Name,PrincipalSource,ObjectClass
Anyone in Administrators who is not Administrator or your expected admin group is worth a question. Domain group nesting is resolved automatically.
Failed logons in the last hour, grouped by user and source IP
Get-WinEvent -FilterHashtable @{LogName='Security';Id=4625;StartTime=(Get-Date).AddHours(-1)} -ErrorAction SilentlyContinue | Select-Object @{N='User';E={$_.Properties[5].Value}},@{N='IP';E={$_.Properties[19].Value}} | Group-Object User,IP | Sort-Object Count -Descending | Select-Object Count,Name -First 20
The fastest way to confirm or rule out an active password attack. For a fleet-wide view, fan the same query out across all DCs with Invoke-Command.
Frequently Asked Questions
Are these one-liners safe to run on production systems?
All of them are read-only. The CPU impact is negligible on modern hardware. The only operational risk is the filesystem walk on C:\ — on a server with millions of files that can take minutes and produce a long list. Scope it tighter when in doubt.
Do I need to be a local administrator?
Some — yes. CommandLine on Win32_Process, the Security event log, and most registry hives under HKLM require elevation. Without it, the same one-liner silently returns fewer rows, which is misleading. Always run from an elevated shell.
Can I run these against remote machines?
Yes. Wrap any snippet in Invoke-Command -ComputerName $list -ScriptBlock { ... }. The returned objects are deserialised, so most downstream pipeline operators still work. See the remote management guide linked below.
Why not just use Defender for Endpoint or a SIEM?
You should — for ongoing monitoring. These one-liners are for the moment you do not have the tool, the agent has not yet been deployed, or you need to confirm something interactively before paging an analyst. They complement, not replace, proper telemetry.
How do I export the output for a colleague?
Append | Export-Csv -Path .\out.csv -NoTypeInformation -Encoding UTF8BOM to any of them. The CSV export guide linked below covers the encoding flags that keep Excel from mangling non-ASCII characters.
Conclusion
A useful one-liner is one you can type from memory at 2 a.m. when something is on fire. Pick the four or five from this list that map to the questions you most often ask, drop them in a profile module, and they become reflexes. They will not solve a real incident on their own — that is what your EDR, SIEM, and IR runbook are for — but they will get you to "is this actually a problem?" within minutes rather than hours.
Related Posts
- PowerShell Quick Guide: Process Investigation — the full version of the process triage covered in the first one-liners.
- PowerShell Quick Guide: Remote Management Basics — how to fan these snippets out across a fleet.
- Windows Security: Detecting Malicious Scheduled Tasks — deeper detection of the persistence layer hinted at above.
Reference for the WMI/CIM provider that most of these snippets lean on: CIM Win32 Provider on Microsoft Learn.
0 comments:
Post a Comment