When a security alert appears, a clear sequence matters more than speed alone. This playbook gives a practical step-by-step workflow you can run in authorized environments using native Windows + PowerShell.
Step 1: Confirm authentication anomalies
Start by checking failed logons, lockouts, and successful logons in the same period.
# Failed logons
Get-WinEvent -FilterHashtable @{
LogName='Security'
Id=4625
StartTime=(Get-Date).AddHours(-2)
} | Select-Object TimeCreated, Id, Message -First 200
# Lockouts
Get-WinEvent -FilterHashtable @{
LogName='Security'
Id=4740
StartTime=(Get-Date).AddHours(-2)
} | Select-Object TimeCreated, Id, Message
# Successful logons
Get-WinEvent -FilterHashtable @{
LogName='Security'
Id=4624
StartTime=(Get-Date).AddHours(-2)
} | Select-Object TimeCreated, Id, Message -First 200
What to check: repeated source hosts, failed-to-successful patterns, unusual account usage.
Step 2: Validate account and privilege changes
Check whether users/groups changed around the same time as the alert.
# User account created
Get-WinEvent -FilterHashtable @{ LogName='Security'; Id=4720; StartTime=(Get-Date).AddDays(-1) } |
Select-Object TimeCreated, Id, Message
# User account deleted
Get-WinEvent -FilterHashtable @{ LogName='Security'; Id=4726; StartTime=(Get-Date).AddDays(-1) } |
Select-Object TimeCreated, Id, Message
# Group membership changes
Get-WinEvent -FilterHashtable @{ LogName='Security'; Id=4732; StartTime=(Get-Date).AddDays(-1) } |
Select-Object TimeCreated, Id, Message
Get-WinEvent -FilterHashtable @{ LogName='Security'; Id=4733; StartTime=(Get-Date).AddDays(-1) } |
Select-Object TimeCreated, Id, Message
Step 3: Inspect process execution
Find suspicious process launches and high-resource processes.
# Process creation events
Get-WinEvent -FilterHashtable @{
LogName='Security'
Id=4688
StartTime=(Get-Date).AddHours(-2)
} | Select-Object TimeCreated, Id, Message -First 200
# Current high CPU processes
Get-Process | Sort-Object CPU -Descending |
Select-Object -First 25 Name, Id, CPU, Path
What to check: executables launched from temp/user-writable locations, unknown binaries, unusual parent-child process behavior.
Step 4: Check persistence indicators
# New service installed
Get-WinEvent -FilterHashtable @{
LogName='System'
Id=7045
StartTime=(Get-Date).AddDays(-1)
} | Select-Object TimeCreated, Id, Message
If available in your environment, also review scheduled tasks and startup changes.
Step 5: Build a network activity snapshot
# Active established sessions
Get-NetTCPConnection -State Established |
Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort, OwningProcess
# Map process IDs
Get-Process | Select-Object Id, Name, Path
What to check: unusual outbound destinations, uncommon remote ports, repeated connections from unexpected processes.
Step 6: Verify log integrity and endpoint detections
# Security log cleared
Get-WinEvent -FilterHashtable @{
LogName='Security'
Id=1102
StartTime=(Get-Date).AddDays(-2)
} | Select-Object TimeCreated, Id, Message
# Defender malware detections
Get-WinEvent -FilterHashtable @{
LogName='Microsoft-Windows-Windows Defender/Operational'
Id=1116
StartTime=(Get-Date).AddDays(-7)
} | Select-Object TimeCreated, Id, Message
Step 7: Export evidence immediately
$Out = "C:\Temp\triage_$(Get-Date -Format yyyyMMdd_HHmmss)"
New-Item -Path $Out -ItemType Directory -Force | Out-Null
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625; StartTime=(Get-Date).AddHours(-6)} |
Select TimeCreated, Id, Message |
Export-Csv "$Out\failed_logons.csv" -NoTypeInformation
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4740; StartTime=(Get-Date).AddHours(-6)} |
Select TimeCreated, Id, Message |
Export-Csv "$Out\lockouts.csv" -NoTypeInformation
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4688; StartTime=(Get-Date).AddHours(-6)} |
Select TimeCreated, Id, Message |
Export-Csv "$Out\process_create_4688.csv" -NoTypeInformation
Get-NetTCPConnection -State Established |
Select LocalAddress, LocalPort, RemoteAddress, RemotePort, OwningProcess |
Export-Csv "$Out\net_connections.csv" -NoTypeInformation
Get-Process |
Select Name, Id, CPU, Path |
Export-Csv "$Out\process_list.csv" -NoTypeInformation
Step 8: Write a concise incident summary
- Trigger and detection source
- Top indicators observed
- Affected users/systems
- Containment actions completed
- Next action and owner
This sequence keeps triage consistent, evidence-focused, and easier to hand off across teams.
