Skip to content

PowerShell Live Response & Incident Triage Scripts

Essential non-destructive PowerShell commands and modular functions for live-response investigation during active incident triage.


🌐 1. Active Network Connections with Process Attribution

Section titled “🌐 1. Active Network Connections with Process Attribution”
  • 🎯 What it looks for: Established and listening TCP/UDP network connections, mapping each socket’s local and remote IP:Port directly to the owning Process ID, Process Name, executable file path, and exact command-line arguments.
  • 💡 Why it matters: Standard netstat output only shows Process IDs, requiring manual correlation. Attackers operating C2 beacons or reverse shells often name their binaries after benign tools (svchost.exe, update.exe); mapping the socket directly to the binary path reveals whether the connection is spawned from abnormal paths like C:\Users\Public\, C:\ProgramData\, or AppData.
Terminal window
# Get active TCP connections mapped to Process Name and Command Line
Get-NetTCPConnection -State Established, Listen | ForEach-Object {
$conn = $_
$proc = Get-CimInstance Win32_Process -Filter "ProcessId = $($conn.OwningProcess)"
[PSCustomObject]@{
LocalAddress = "$($conn.LocalAddress):$($conn.LocalPort)"
RemoteAddress = "$($conn.RemoteAddress):$($conn.RemotePort)"
State = $conn.State
PID = $conn.OwningProcess
ProcessName = $proc.Name
Executable = $proc.ExecutablePath
CommandLine = $proc.CommandLine
}
} | Sort-Object RemoteAddress | Out-GridView -Title "Active Sockets vs Process"

⚡ 2. Process Parentage & Suspicious Hierarchy Triage

Section titled “⚡ 2. Process Parentage & Suspicious Hierarchy Triage”
  • 🎯 What it looks for: Command-line interpreters (powershell.exe, cmd.exe, mshta.exe, wscript.exe) spawned by anomalous parent processes such as web application worker pools (w3wp.exe), SQL servers (sqlservr.exe), the print spooler (spoolsv.exe), or desktop shell processes.
  • 💡 Why it matters: Adversaries exploiting vulnerabilities (e.g. Log4j, web shells, remote code execution bugs) inherit the context of the vulnerable parent service. A database server or print spooler spawning PowerShell is almost always an active exploit attempt or privilege escalation payload.
Terminal window
# Extract process tree with parent attribution
$processes = Get-CimInstance Win32_Process | Select-Object ProcessId, ParentProcessId, Name, ExecutablePath, CommandLine
$procLookup = @{}
$processes | ForEach-Object { $procLookup[$_.ProcessId] = $_.Name }
$processes | ForEach-Object {
[PSCustomObject]@{
PID = $_.ProcessId
ProcessName = $_.Name
ParentPID = $_.ParentProcessId
ParentName = $procLookup[$_.ParentProcessId]
CommandLine = $_.CommandLine
Path = $_.ExecutablePath
}
} | Where-Object {
$_.ProcessName -in 'powershell.exe','cmd.exe','cscript.exe','wscript.exe','mshta.exe' -and
$_.ParentName -in 'w3wp.exe','sqlservr.exe','spoolsv.exe','explorer.exe'
} | Format-Table -AutoSize

🔍 3. Unsigned Running Binaries Inspection

Section titled “🔍 3. Unsigned Running Binaries Inspection”
  • 🎯 What it looks for: All unique executables currently running in system memory that lack a valid cryptographic Authenticode digital signature, have revoked certificates, or are self-signed.
  • 💡 Why it matters: Enterprise workstations run Microsoft-signed and trusted vendor software. Custom adversary payloads, Cobalt Strike beacons, compiled loaders, and ransomware executables are frequently unsigned or signed with fake, invalid certificates that fail chain verification.
Terminal window
# Identify unsigned or invalid signature executables running in memory
Get-Process | Select-Object -ExpandProperty Path -Unique | Where-Object { $_ } | ForEach-Object {
$sig = Get-AuthenticodeSignature -FilePath $_
if ($sig.Status -ne 'Valid') {
[PSCustomObject]@{
Status = $sig.Status
SignerCert = $sig.SignerCertificate.Subject
Path = $_
}
}
} | Format-Table -AutoSize

  • 🎯 What it looks for: Inspects common autostart registry hives (Run, RunOnce) across both HKLM (system-wide) and HKCU (current user), including 32-bit WOW6432Node locations.
  • 💡 Why it matters: Registry Run keys remain one of the most reliable and frequently abused persistence vectors. Malware places payloads in user directories (%APPDATA%, %TEMP%) and creates a Run key to guarantee execution upon every user logon without requiring local administrator rights.
Terminal window
# Registry Run & RunOnce Keys (User + System)
$runPaths = @(
"HKLM:\Software\Microsoft\Windows\CurrentVersion\Run",
"HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce",
"HKCU:\Software\Microsoft\Windows\CurrentVersion\Run",
"HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce",
"HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Run"
)
$runItems = foreach ($path in $runPaths) {
if (Test-Path $path) {
Get-ItemProperty -Path $path | Get-Member -MemberType NoteProperty | ForEach-Object {
[PSCustomObject]@{
Hive = $path
Entry = $_.Name
Value = (Get-ItemProperty -Path $path).($_.Name)
}
}
}
}
$runItems | Where-Object { $_.Entry -notmatch '^PS' } | Format-Table -AutoSize

🕒 5. Active Scheduled Tasks Executing Script Interpreters

Section titled “🕒 5. Active Scheduled Tasks Executing Script Interpreters”
  • 🎯 What it looks for: Scheduled Tasks configured to invoke script interpreters (powershell.exe, cmd.exe, rundll32.exe, mshta.exe, cscript.exe) along with their configured arguments and trigger state.
  • 💡 Why it matters: Attackers use scheduled tasks to maintain persistent footholds that trigger periodically (e.g. every 30 minutes) or upon system idle. Auditing tasks running command interpreters highlights obfuscated scripts, remote downloads, or beacon resurrectors.
Terminal window
# Filter scheduled tasks invoking cmd, powershell, or wscript
Get-ScheduledTask | Where-Object {
$_.Actions.Execute -match '(powershell|cmd|cscript|wscript|mshta|rundll32)'
} | Select-Object TaskName, TaskPath, State, @{N='Command';E={$_.Actions.Execute}}, @{N='Arguments';E={$_.Actions.Arguments}} | Format-Table -AutoSize

  • 🎯 What it looks for: Inspects the client-side Windows DNS cache (DnsClientCache), revealing all external domain names and hostnames resolved by local processes, along with their remaining Time-To-Live (TTL).
  • 💡 Why it matters: If an attacker runs a C2 beacon or drops an infostealer that contacts external command infrastructure, the domain is cached locally prior to network transmission. Even if the network socket has closed, the DNS cache preserves volatile evidence of C2 domains, dynamic DNS hosts, and webhook exfiltration endpoints.
Terminal window
# Inspect recent DNS lookups
Get-DnsClientCache | Where-Object { $_.Data -ne $null } |
Select-Object Entry, RecordName, RecordType, Status, Data, TimeToLive |
Sort-Object TimeToLive |
Out-GridView -Title "DNS Cache Audit"