← All cheat sheets

POWERSHELL FOR BLUE TEAM

Plain-text reference · 11 KB. Read it, search it (Ctrl-F) or print it.

PowerShell commands for incident response, threat hunting, log
analysis, hardening, and security monitoring on Windows systems.

INCIDENT RESPONSE#

# Current user and privileges
whoami /all
[Security.Principal.WindowsIdentity]::GetCurrent().Name
([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

# Running processes
Get-Process | Sort-Object CPU -Descending | Select-Object -First 20
Get-Process | Where-Object {$_.Path -notlike "C:\Windows\*"} | Select-Object Name, Path, Id
Get-CimInstance Win32_Process | Select-Object ProcessId, Name, CommandLine, ParentProcessId

# Process with parent process mapping
Get-CimInstance Win32_Process | Select-Object ProcessId, ParentProcessId, Name, CommandLine | Format-Table -AutoSize

# Suspicious processes
Get-Process | Where-Object {$_.Path -like "*\Temp\*" -or $_.Path -like "*\AppData\*"}

# Network connections
Get-NetTCPConnection | Where-Object {$_.State -eq "Established"} | Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort, OwningProcess
Get-NetTCPConnection | Where-Object {$_.RemoteAddress -notlike "127.*" -and $_.RemoteAddress -notlike "0.0.0.0"} | Sort-Object RemoteAddress

# Process → network correlation
Get-NetTCPConnection -State Established | ForEach-Object {
    $proc = Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue
    [PSCustomObject]@{
        LocalPort = $_.LocalPort; RemoteAddress = $_.RemoteAddress
        RemotePort = $_.RemotePort; Process = $proc.ProcessName
        Path = $proc.Path; PID = $_.OwningProcess
    }
} | Format-Table -AutoSize

# DNS cache
Get-DnsClientCache | Select-Object Entry, RecordName, Data
Get-DnsClientCache | Where-Object {$_.Entry -like "*.xyz" -or $_.Entry -like "*.top"}

# Startup items
Get-CimInstance Win32_StartupCommand | Select-Object Name, Command, Location, User
Get-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run"
Get-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run"

# Scheduled tasks
Get-ScheduledTask | Where-Object {$_.State -ne "Disabled"} | Select-Object TaskName, TaskPath, State
Get-ScheduledTask | ForEach-Object { $_ | Select-Object TaskName, @{N='Action';E={($_.Actions).Execute}} }

# Services
Get-Service | Where-Object {$_.Status -eq "Running"} | Sort-Object DisplayName
Get-CimInstance Win32_Service | Where-Object {$_.PathName -notlike "C:\Windows\*"} | Select-Object Name, PathName, StartMode

# Installed software
Get-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*" | Select-Object DisplayName, InstallDate, Publisher | Sort-Object InstallDate -Descending

# Recent file modifications
Get-ChildItem -Path C:\ -Recurse -ErrorAction SilentlyContinue | Where-Object {$_.LastWriteTime -gt (Get-Date).AddHours(-24)} | Select-Object FullName, LastWriteTime | Sort-Object LastWriteTime -Descending

# Unsigned DLLs loaded
Get-Process | ForEach-Object {
    $_.Modules | Where-Object {-not (Get-AuthenticodeSignature $_.FileName -ErrorAction SilentlyContinue).Status -eq "Valid"}
} | Select-Object FileName -Unique

EVENT LOG ANALYSIS#

# Failed logons (4625)
Get-WinEvent -FilterHashtable @{LogName='Security';Id=4625} -MaxEvents 50 |
    ForEach-Object { [PSCustomObject]@{
        Time = $_.TimeCreated
        User = $_.Properties[5].Value
        Source = $_.Properties[19].Value
        Status = $_.Properties[7].Value
    }} | Format-Table

# Successful logons (4624)
Get-WinEvent -FilterHashtable @{LogName='Security';Id=4624} -MaxEvents 50 |
    Where-Object {$_.Properties[8].Value -notin @(5,7)} |  # Exclude service/unlock
    ForEach-Object { [PSCustomObject]@{
        Time = $_.TimeCreated
        User = $_.Properties[5].Value
        LogonType = $_.Properties[8].Value
        Source = $_.Properties[18].Value
    }} | Format-Table

# Process creation (4688)
Get-WinEvent -FilterHashtable @{LogName='Security';Id=4688} -MaxEvents 100 |
    ForEach-Object { [PSCustomObject]@{
        Time = $_.TimeCreated
        User = $_.Properties[1].Value
        Process = $_.Properties[5].Value
        CommandLine = $_.Properties[8].Value
    }} | Format-Table -Wrap

# PowerShell script block logging (4104)
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-PowerShell/Operational';Id=4104} -MaxEvents 50 |
    Select-Object TimeCreated, @{N='ScriptBlock';E={$_.Properties[2].Value}}

# Service installations (7045)
Get-WinEvent -FilterHashtable @{LogName='System';Id=7045} -MaxEvents 20 |
    ForEach-Object { [PSCustomObject]@{
        Time = $_.TimeCreated
        ServiceName = $_.Properties[0].Value
        ImagePath = $_.Properties[1].Value
        AccountName = $_.Properties[4].Value
    }} | Format-Table -Wrap

# Cleared event logs (1102)
Get-WinEvent -FilterHashtable @{LogName='Security';Id=1102} -ErrorAction SilentlyContinue

# Time range query
$start = (Get-Date).AddDays(-7)
$end = Get-Date
Get-WinEvent -FilterHashtable @{LogName='Security';Id=4625;StartTime=$start;EndTime=$end}

# Search all logs for keyword
Get-WinEvent -ListLog * | ForEach-Object {
    Get-WinEvent -FilterHashtable @{LogName=$_.LogName} -MaxEvents 100 -ErrorAction SilentlyContinue |
    Where-Object {$_.Message -like "*mimikatz*"}
}

THREAT HUNTING#

# Find encoded PowerShell
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-PowerShell/Operational';Id=4104} |
    Where-Object {$_.Properties[2].Value -match "FromBase64String|EncodedCommand|-enc |-e "}

# Suspicious parent-child processes
Get-CimInstance Win32_Process |
    Where-Object {$_.ParentProcessId -ne 0} |
    ForEach-Object {
        $parent = Get-Process -Id $_.ParentProcessId -ErrorAction SilentlyContinue
        [PSCustomObject]@{
            PID = $_.ProcessId; Name = $_.Name
            ParentPID = $_.ParentProcessId; ParentName = $parent.ProcessName
            CommandLine = $_.CommandLine
        }
    } | Where-Object {
        ($_.ParentName -eq "winword" -and $_.Name -match "cmd|powershell") -or
        ($_.ParentName -eq "excel" -and $_.Name -match "cmd|powershell")
    }

# Find persistence mechanisms
# Registry autoruns
$paths = @(
    "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run",
    "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run",
    "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce",
    "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon"
)
$paths | ForEach-Object { Get-ItemProperty $_ -ErrorAction SilentlyContinue }

# WMI event subscriptions
Get-WMIObject -Namespace root/subscription -Class __EventFilter
Get-WMIObject -Namespace root/subscription -Class __EventConsumer
Get-WMIObject -Namespace root/subscription -Class __FilterToConsumerBinding

# Alternate data streams
Get-ChildItem -Path C:\Users -Recurse -Stream * -ErrorAction SilentlyContinue |
    Where-Object {$_.Stream -ne ':$DATA'}

# Recently created accounts
Get-LocalUser | Where-Object {$_.Enabled -and $_.LastLogon -gt (Get-Date).AddDays(-30)} |
    Select-Object Name, Enabled, LastLogon, PasswordLastSet

# Find files in suspicious locations
Get-ChildItem -Path "C:\Windows\Temp","C:\Users\*\AppData\Local\Temp" -Recurse -File |
    Where-Object {$_.Extension -match "\.exe|\.dll|\.ps1|\.bat|\.vbs"} |
    Select-Object FullName, CreationTime, Length

HARDENING#

# Disable SMBv1
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force
Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol

# Enable PowerShell logging
# Script block logging
New-ItemProperty -Path "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -Name "EnableScriptBlockLogging" -Value 1 -PropertyType DWord -Force

# Module logging
New-ItemProperty -Path "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ModuleLogging" -Name "EnableModuleLogging" -Value 1 -PropertyType DWord -Force

# Enable command line in process creation events
New-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\Audit" -Name "ProcessCreationIncludeCmdLine_Enabled" -Value 1 -PropertyType DWord -Force

# Windows Firewall
Get-NetFirewallProfile | Select-Object Name, Enabled
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled True
New-NetFirewallRule -DisplayName "Block Outbound SMB" -Direction Outbound -Protocol TCP -RemotePort 445 -Action Block

# Check Windows Defender status
Get-MpComputerStatus | Select-Object AntivirusEnabled, RealTimeProtectionEnabled, AntivirusSignatureLastUpdated
Get-MpThreatDetection | Select-Object -First 10

# Audit policy
auditpol /get /category:*
auditpol /set /subcategory:"Logon" /success:enable /failure:enable
auditpol /set /subcategory:"Process Creation" /success:enable

ACTIVE DIRECTORY QUERIES#

Import-Module ActiveDirectory

# Locked out accounts
Search-ADAccount -LockedOut | Select-Object Name, LastLogonDate

# Password never expires
Get-ADUser -Filter {PasswordNeverExpires -eq $true} -Properties PasswordNeverExpires | Select-Object Name, Enabled

# Admins
Get-ADGroupMember "Domain Admins" | Select-Object Name, SamAccountName
Get-ADGroupMember "Enterprise Admins" | Select-Object Name, SamAccountName

# Inactive accounts (90+ days)
$cutoff = (Get-Date).AddDays(-90)
Get-ADUser -Filter {LastLogonDate -lt $cutoff -and Enabled -eq $true} -Properties LastLogonDate | Select-Object Name, LastLogonDate

# Kerberoastable accounts
Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName | Select-Object Name, ServicePrincipalName

# Recently created users
Get-ADUser -Filter {WhenCreated -gt $cutoff} -Properties WhenCreated | Select-Object Name, WhenCreated

NETWORK MONITORING#

# Test connectivity
Test-NetConnection -ComputerName 10.10.10.5 -Port 445
Test-NetConnection -ComputerName target.com -Port 443 -InformationLevel Detailed

# ARP table
Get-NetNeighbor | Where-Object {$_.State -eq "Reachable"} | Select-Object IPAddress, LinkLayerAddress, InterfaceAlias

# Listening ports
Get-NetTCPConnection -State Listen | Select-Object LocalAddress, LocalPort, OwningProcess |
    ForEach-Object { $_ | Add-Member -NotePropertyName "ProcessName" -NotePropertyValue (Get-Process -Id $_.OwningProcess).ProcessName -PassThru } | Format-Table

# SMB shares
Get-SmbShare | Select-Object Name, Path, Description
Get-SmbSession | Select-Object ClientComputerName, ClientUserName, NumOpens

FILE INTEGRITY#

# Hash a file
Get-FileHash C:\Windows\System32\cmd.exe -Algorithm SHA256

# Hash all files in directory
Get-ChildItem C:\Windows\System32\*.exe | Get-FileHash -Algorithm SHA256 | Export-Csv hashes.csv

# Compare file hashes (baseline vs current)
$baseline = Import-Csv baseline_hashes.csv
$current = Get-ChildItem C:\Windows\System32\*.exe | Get-FileHash
Compare-Object $baseline $current -Property Hash, Path

TIPS#

  - Enable Script Block Logging for PowerShell visibility
  - Enable Process Creation auditing with command line
  - Get-WinEvent is faster than Get-EventLog
  - Use -FilterHashtable for efficient event log queries
  - Export results to CSV for timeline analysis
  - Test-NetConnection replaces telnet for port testing
  - Get-FileHash for integrity checking and IOC matching
  - WMI subscriptions are a common persistence mechanism
  - Check both HKLM and HKCU Run keys for autoruns
  - Use Transcription logging to capture all PS activity

Defensive reference on CyberRamen. Offensive / red-team sheets live on OffensiveRamen.com.