Free Cheatsheet

PowerShell for Security Operations

The commands defenders run during investigations and triage, organized by ATT&CK tactic. 31 commands across 9 tactics, each with the syntax, what it reveals, and what to look for. No account needed.

Run elevated where required. These are read-and-collect commands for investigation and triage, paired with what each output reveals and how to read it. Organized by the ATT&CK tactic the command helps you investigate.

Discovery 6

Local System InformationT1082
Get-ComputerInfo | Select-Object CsName, OsName, OsVersion, OsBuildNumber, CsDomain, CsWorkgroup, TimeZone
What it reveals
Collects OS version, build, domain membership, and timezone. Establishes the baseline identity of the system under investigation.
How to investigate
Compare domain membership against expected OU. Check if timezone matches the user expected location. Build number reveals patch level.
Network ConfigurationT1016
Get-NetIPConfiguration | Select-Object InterfaceAlias, IPv4Address, DNSServer, DefaultGateway
What it reveals
Reveals all network interfaces, IPs, DNS servers, and gateways. Identifies dual-homed hosts or unexpected network connections.
How to investigate
Multiple active interfaces may indicate the host is bridging networks. DNS servers pointing to unexpected IPs could indicate DNS hijacking.
Domain ControllersT1018
Get-ADDomainController -Filter * | Select-Object Name, IPv4Address, Site, OperatingSystem, IsGlobalCatalog
What it reveals
Enumerates all domain controllers, their IPs, sites, and roles. Establishes the AD infrastructure topology for the investigation.
How to investigate
Verify all DCs are known and expected. Unknown DCs could indicate a rogue DC attack (DCShadow). Check OS versions for unpatched controllers.
Local Users and GroupsT1087.001
Get-LocalUser | Select-Object Name, Enabled, LastLogon, PasswordLastSet, Description Get-LocalGroupMember -Group "Administrators" | Select-Object Name, ObjectClass, PrincipalSource
What it reveals
Lists local accounts and local administrator group membership. Critical for identifying accounts created by attackers for persistence.
How to investigate
Accounts with recent PasswordLastSet during the compromise window are suspicious. Unexpected members of the local Administrators group indicate privilege escalation.
AD User EnumerationT1087.002
Get-ADUser -Filter * -Properties LastLogonDate, PasswordLastSet, Enabled, MemberOf | Where-Object { $_.Enabled -eq $true } | Select-Object Name, SamAccountName, LastLogonDate, PasswordLastSet
What it reveals
Enumerates all enabled AD user accounts with logon and password timestamps. Baseline for identifying compromised or attacker-created accounts.
How to investigate
Sort by PasswordLastSet to find recently changed passwords. Accounts with LastLogonDate during the compromise window but no corresponding help desk ticket warrant investigation.
Shared ResourcesT1135
Get-SmbShare | Select-Object Name, Path, Description Get-SmbOpenFile | Select-Object ClientComputerName, ClientUserName, Path
What it reveals
Lists SMB shares and currently open files. Reveals what data is accessible and who is accessing it right now.
How to investigate
Open files from unexpected client IPs during the compromise window indicate active data access. Check for administrative shares (C$, ADMIN$) accessed from non-admin workstations.

Persistence 5

Registry Run KeysT1547.001
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" -ErrorAction SilentlyContinue Get-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -ErrorAction SilentlyContinue Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" -ErrorAction SilentlyContinue
What it reveals
Checks the three primary auto-start registry locations. Malware and persistence tools register here to survive reboots.
How to investigate
Entries pointing to temp directories, encoded commands, or user-writable paths are suspicious. Legitimate entries reference Program Files or Windows directories.
Scheduled TasksT1053.005
Get-ScheduledTask | Where-Object { $_.State -ne "Disabled" } | Select-Object TaskName, TaskPath, State, @{N="Actions";E={$_.Actions.Execute + " " + $_.Actions.Arguments}} | Format-List
What it reveals
Lists all enabled scheduled tasks with their actions. Attackers create tasks for persistence, remote execution, and timed payload delivery.
How to investigate
Tasks with encoded PowerShell, tasks running from temp/ProgramData, tasks created during the compromise window, and tasks running as SYSTEM from non-standard paths.
ServicesT1543.003
Get-WmiObject Win32_Service | Where-Object { $_.PathName -match "temp|appdata|programdata|users" } | Select-Object Name, DisplayName, State, StartMode, PathName
What it reveals
Filters services to those running from user-writable directories. Legitimate services run from System32 or Program Files, anything else warrants scrutiny.
How to investigate
Services with paths containing temp, AppData, ProgramData, or user profile directories. Check if the service was created during the compromise window using registry timestamps.
WMI Event SubscriptionsT1546.003
Get-WMIObject -Namespace root\subscription -Class __EventFilter Get-WMIObject -Namespace root\subscription -Class __EventConsumer Get-WMIObject -Namespace root\subscription -Class __FilterToConsumerBinding
What it reveals
Checks for WMI-based persistence. A complete WMI persistence setup requires all three: an EventFilter (trigger), EventConsumer (action), and FilterToConsumerBinding (link). If all three exist with suspicious content, persistence is confirmed.
How to investigate
CommandLineEventConsumer or ActiveScriptEventConsumer with encoded commands or download cradles. Filters triggering on logon events or timers.
Startup Folder ContentsT1547.001
Get-ChildItem "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup" Get-ChildItem "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup"
What it reveals
Lists files in user and system startup folders. Anything placed here executes automatically at logon.
How to investigate
LNK files pointing to suspicious executables, scripts (.bat, .vbs, .ps1), or executables dropped during the compromise window.

Credential Access 3

Cached Credentials CheckT1003
reg query "HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" /v UseLogonCredential Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" | Select-Object RunAsPPL, LmCompatibilityLevel
What it reveals
Checks if WDigest plaintext credential caching is enabled (UseLogonCredential=1) and whether LSA protection (RunAsPPL) is active. WDigest enabled = Mimikatz can extract plaintext passwords.
How to investigate
UseLogonCredential=1 means plaintext passwords are in memory. RunAsPPL=0 means LSASS is unprotected. Both conditions together = credentials are highly exposed.
Kerberos Ticket EnumerationT1558
klist klist sessions
What it reveals
Lists the Kerberos tickets cached for the current session. Reveals which services the user has tickets for and when they expire.
How to investigate
Tickets for services the user should not access. Tickets with unusually long lifetimes (Golden Ticket = 10 years default). Tickets requested for many different services from a single session (Kerberoasting).
SPN Enumeration (Kerberoast Targets)T1558.003
Get-ADUser -Filter { ServicePrincipalName -ne "$null" } -Properties ServicePrincipalName, PasswordLastSet | Select-Object SamAccountName, ServicePrincipalName, PasswordLastSet, Enabled
What it reveals
Identifies accounts with SPNs set, these are Kerberoasting targets. Attackers request TGS tickets for these accounts and crack them offline.
How to investigate
Service accounts with old PasswordLastSet dates and weak passwords are the highest risk. Accounts with SPNs that are also members of privileged groups (Domain Admins) are critical.

Execution 3

Running Processes with Command LinesT1059
Get-WmiObject Win32_Process | Select-Object ProcessId, Name, CommandLine, @{N="ParentPID";E={$_.ParentProcessId}} | Sort-Object ParentPID | Format-List
What it reveals
Lists all running processes with full command lines and parent PIDs. The single most important triage command, reveals what is actively running on the system.
How to investigate
Encoded PowerShell (-enc), processes from temp directories, unusual parent-child relationships (Word/Excel spawning cmd/PowerShell), LOLBins with suspicious arguments.
PowerShell Execution PolicyT1059.001
Get-ExecutionPolicy -List Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell" -Name ExecutionPolicy -ErrorAction SilentlyContinue
What it reveals
Shows the execution policy at each scope level. Attackers may have changed it to bypass restrictions.
How to investigate
Compare current policy against organizational baseline. If changed from Restricted to Unrestricted or Bypass during the compromise window, the attacker modified it to run scripts.
Recently Modified ExecutablesT1036
Get-ChildItem -Path C:\Windows\Temp, $env:TEMP, $env:APPDATA -Include *.exe,*.dll,*.ps1,*.bat,*.vbs -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-7) } | Select-Object FullName, LastWriteTime, Length
What it reveals
Finds executables and scripts recently written to temp and user directories. Malware and attack tools are typically dropped in these locations.
How to investigate
Executables in temp directories created during the compromise window. DLLs in unexpected locations (potential side-loading). Scripts with obfuscated names.

Lateral Movement 4

Active Network ConnectionsT1021
Get-NetTCPConnection -State Established | Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort, OwningProcess, @{N="Process";E={(Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue).ProcessName}} | Sort-Object RemoteAddress
What it reveals
Lists all established TCP connections with the owning process. Reveals active C2 connections and lateral movement sessions.
How to investigate
Connections on port 445 (SMB), 5985/5986 (WinRM), 3389 (RDP) to internal hosts indicate lateral movement. Outbound connections to external IPs from LOLBins indicate C2.
RDP Session HistoryT1021.001
Get-ItemProperty "HKCU:\Software\Microsoft\Terminal Server Client\Servers\*" -ErrorAction SilentlyContinue | Select-Object PSChildName, UsernameHint Get-WinEvent -LogName "Microsoft-Windows-TerminalServices-LocalSessionManager/Operational" -MaxEvents 50 | Select-Object TimeCreated, Id, Message
What it reveals
Shows outbound RDP history (registry) and inbound RDP sessions (event log). Reveals the lateral movement path.
How to investigate
Registry Servers key shows where this host has RDP-connected to (attacker pivot chain). Event log shows who connected inbound. Correlate timestamps with the compromise timeline.
SMB Sessions and Open FilesT1021.002
Get-SmbSession | Select-Object ClientComputerName, ClientUserName, NumOpens Get-SmbOpenFile | Select-Object ClientComputerName, ClientUserName, Path
What it reveals
Lists active SMB sessions and currently open remote files. Reveals live lateral movement or data access in progress.
How to investigate
SMB sessions from unexpected hosts or using service accounts. Open files on administrative shares (C$, ADMIN$) from workstations = lateral movement tool activity.
Remote WinRM SessionsT1021.006
Get-WSManInstance -ResourceURI shell -Enumerate Get-WinEvent -LogName "Microsoft-Windows-WinRM/Operational" -MaxEvents 20 | Select-Object TimeCreated, Id, Message
What it reveals
Lists active WinRM shells and recent WinRM event log entries. WinRM is used by PowerShell Remoting and is a common lateral movement technique.
How to investigate
Active WinRM shells from unexpected source IPs. WinRM sessions initiated during the compromise window. Combined with PSExec or Invoke-Command evidence.

Collection 2

Recently Accessed FilesT1005
Get-ChildItem "$env:APPDATA\Microsoft\Windows\Recent" -ErrorAction SilentlyContinue | Sort-Object LastWriteTime -Descending | Select-Object Name, LastWriteTime -First 30
What it reveals
Lists the 30 most recently accessed files via the Recent Items folder. Shows what the user (or attacker) was looking at.
How to investigate
Sensitive documents accessed during the compromise window: financial data, HR records, credentials files, architecture diagrams. Archive files (.zip, .rar, .7z) suggest staging for exfiltration.
Large Files and ArchivesT1074
Get-ChildItem -Path C:\Users -Include *.zip,*.rar,*.7z,*.tar,*.gz -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.Length -gt 10MB } | Select-Object FullName, @{N="SizeMB";E={[math]::Round($_.Length/1MB,1)}}, LastWriteTime
What it reveals
Finds large archive files in user directories. Attackers stage data in archives before exfiltration.
How to investigate
Archives created during the compromise window in temp, Desktop, or Downloads directories. Multiple archives created in quick succession suggest automated collection.

Defense Evasion 3

Defender Status and ExclusionsT1562.001
Get-MpComputerStatus | Select-Object RealTimeProtectionEnabled, AntivirusEnabled, AntispywareEnabled, BehaviorMonitorEnabled Get-MpPreference | Select-Object -ExpandProperty ExclusionPath Get-MpPreference | Select-Object -ExpandProperty ExclusionProcess
What it reveals
Checks if Defender protection components are active and lists configured exclusions. Attackers disable protection or add exclusions for their tool directories.
How to investigate
Any protection component disabled = defense evasion. Exclusions added during the compromise window, especially for temp directories or ProgramData, indicate the attacker prepared the system for tool deployment.
Event Log StatusT1070.001
Get-WinEvent -ListLog Security,System,Application,"Microsoft-Windows-PowerShell/Operational","Microsoft-Windows-Sysmon/Operational" -ErrorAction SilentlyContinue | Select-Object LogName, IsEnabled, RecordCount, FileSize, LastWriteTime
What it reveals
Checks whether critical log channels are enabled and their current state. Attackers disable logging or clear logs to cover tracks.
How to investigate
Disabled logs = defense evasion. Low record counts with recent LastWriteTime suggest logs were recently cleared. Compare expected log volume against actual record count.
Hidden Files and Alternate Data StreamsT1564
Get-ChildItem -Path C:\Users -Force -Hidden -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-7) } | Select-Object FullName, LastWriteTime, Length Get-Item -Path C:\Users\*\Desktop\* -Stream * -ErrorAction SilentlyContinue | Where-Object { $_.Stream -ne ":$DATA" }
What it reveals
Finds recently created hidden files and files with Alternate Data Streams. Attackers hide tools as hidden files or embed payloads in ADS.
How to investigate
Hidden executables or scripts in user directories. Alternate Data Streams attached to legitimate files, these can contain hidden payloads that execute when the parent file is accessed.

Exfiltration 2

DNS Resolution CacheT1048
Get-DnsClientCache | Select-Object Entry, RecordName, RecordType, Data | Sort-Object Entry
What it reveals
Lists the DNS resolver cache. Reveals what domains the system has recently resolved, including C2 domains, exfiltration endpoints, and tunneling destinations.
How to investigate
High-entropy domain names (DGA). Domains not matching normal business activity. Excessive TXT record lookups (DNS tunneling). Known threat intelligence indicators.
USB Device HistoryT1052
Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Enum\USBSTOR\*\*" -ErrorAction SilentlyContinue | Select-Object FriendlyName, @{N="Serial";E={$_.PSChildName}}, ContainerID
What it reveals
Lists USB storage devices that have been connected to this system. Reveals whether removable media was used for data theft.
How to investigate
USB devices connected during the compromise window. Unknown devices not matching corporate inventory. Correlate device serial numbers across multiple systems to track the same device.

Containment 3

Disable AD AccountResponse
Disable-ADAccount -Identity "compromised_user" Search-ADAccount -LockedOut | Unlock-ADAccount
What it reveals
Disables a compromised AD account and unlocks accounts locked during brute force. The first containment action for any identity compromise.
How to investigate
After disabling, check for the account appearing in subsequent authentication logs, continued activity means the attacker has another access path (token, secondary account).
Revoke Cloud SessionsResponse
# Microsoft Graph PowerShell Revoke-MgUserSignInSession -UserId "user@domain.com" # Reset password Update-MgUser -UserId "user@domain.com" -PasswordProfile @{ ForceChangePasswordNextSignIn = $true }
What it reveals
Revokes all active cloud sessions and forces password change. Essential for M365/Entra ID compromise containment. Token-based access persists until refresh tokens are revoked.
How to investigate
After revocation, monitor SigninLogs for new sessions from the attacker IP. If activity continues, check for OAuth app persistence or certificate-based authentication.
Network Isolation CheckResponse
Test-NetConnection -ComputerName "isolated-host" -Port 445 Get-NetFirewallRule | Where-Object { $_.Action -eq "Block" -and $_.Enabled -eq "True" } | Select-Object DisplayName, Direction
What it reveals
Verifies network isolation is working by testing connectivity and reviewing active firewall blocks.
How to investigate
After isolating a device, verify it cannot reach other hosts on SMB (445), RDP (3389), or WinRM (5985). Active block rules confirm firewall-based containment is in place.

From running commands to running the investigation

These collect the evidence. Windows Endpoint Investigation teaches the method: correlating what they return into a defensible account of what happened on the host, and proving it. Built by practitioners who still do the job.

Explore the course