Skip to content

Collect a Windows Endpoint First-Response Snapshot

When a Windows endpoint shows signs of compromise, collect a focused record of its current state before changing it where your incident plan permits. This snapshot includes host details, processes, network connections, Defender status, and recent system events.

Use an approved administrative session, follow the incident lead’s containment direction, and store the files in a restricted case location. Live response commands can affect the system and do not replace a forensic image or documented evidence-handling process.


Step 1: Create a Restricted Case Folder

01

Prepare an Evidence Collection Directory

Evidence Handling

Open elevated PowerShell, create a uniquely named folder under ProgramData, and restrict inherited permissions so only Local System and local Administrators can read the collection. Keep the shell open for the remaining steps so the case path stays available.

Terminal window
$caseDir = Join-Path $env:ProgramData ('IR\' + (Get-Date -Format 'yyyyMMdd-HHmmss'))
New-Item -ItemType Directory -Path $caseDir -Force | Out-Null
icacls $caseDir /inheritance:r /grant:r '*S-1-5-18:(OI)(CI)F' '*S-1-5-32-544:(OI)(CI)F'
Get-Acl $caseDir | Format-List Owner, AccessToString
@(
"Collector: $env:USERDOMAIN\$env:USERNAME"
"Started UTC: $([DateTime]::UtcNow.ToString('o'))"
) | Set-Content -Path (Join-Path $caseDir 'collection-notes.txt')
❯ View Expected Console Output
processed file: C:\ProgramData\IR\20261004-101500
Successfully processed 1 files

Step 2: Record Host, Process, and Network State

02

Capture the Current Endpoint State

System Triage

Save basic system information, active processes, TCP connections, and local UDP endpoints with their owning process IDs. UDP is connectionless, so this records local endpoints rather than remote peer sessions. These queries do not terminate processes or change firewall rules, though collecting live state can update system metadata and may expose sensitive command lines or addresses.

Terminal window
Get-ComputerInfo |
Select-Object CsName, WindowsProductName, WindowsVersion, OsBuildNumber,
OsLastBootUpTime |
Format-List | Out-File (Join-Path $caseDir 'host.txt')
Get-CimInstance Win32_Process |
Select-Object ProcessId, ParentProcessId, ExecutablePath,
CreationDate, CommandLine |
Export-Csv -NoTypeInformation (Join-Path $caseDir 'processes.csv')
Get-NetTCPConnection |
Select-Object State, LocalAddress, LocalPort, RemoteAddress,
RemotePort, OwningProcess |
Export-Csv -NoTypeInformation (Join-Path $caseDir 'tcp-connections.csv')
Get-NetUDPEndpoint |
Select-Object LocalAddress, LocalPort, OwningProcess |
Export-Csv -NoTypeInformation (Join-Path $caseDir 'udp-endpoints.csv')
❯ View Expected Console Output
host.txt
processes.csv
tcp-connections.csv
udp-endpoints.csv

Step 3: Save Defender Status and Recent System Events

03

Collect Security and Event-Log Context

Security Telemetry

Record Defender’s current status when the module is present and collect a bounded period of recent System events. Adjust the time window to the suspected activity timeline. Event timestamps are converted to UTC ISO 8601 in the export so they can be compared with the UTC collection note; note any event-log access errors.

Terminal window
if (Get-Command Get-MpComputerStatus -ErrorAction SilentlyContinue) {
Get-MpComputerStatus |
Select-Object AMServiceEnabled, AntivirusEnabled,
RealTimeProtectionEnabled, AntivirusSignatureLastUpdated |
Format-List | Out-File (Join-Path $caseDir 'defender-status.txt')
} else {
'Get-MpComputerStatus is unavailable on this endpoint.' |
Set-Content (Join-Path $caseDir 'defender-status.txt')
}
$since = (Get-Date).AddHours(-2)
Get-WinEvent -FilterHashtable @{
LogName = 'System'
StartTime = $since
} -MaxEvents 500 -ErrorAction Continue |
Select-Object @{Name='TimeCreatedUtc'; Expression={ $_.TimeCreated.ToUniversalTime().ToString('o') }},
Id, ProviderName, LevelDisplayName, Message |
Export-Csv -NoTypeInformation (Join-Path $caseDir 'recent-system-events.csv')
❯ View Expected Console Output
defender-status.txt
recent-system-events.csv

Step 4: Hash and Verify the Collected Files

04

Create a SHA-256 Manifest

Integrity Check

Hash the collected files and immediately verify the manifest. If additional evidence is added later, create a new manifest and document the action in the case notes. A matching hash detects later changes to these files; it does not establish that collection was complete or that the live host was trustworthy.

Terminal window
$manifest = Join-Path $caseDir 'SHA256SUMS.csv'
Get-ChildItem -Path $caseDir -File |
Where-Object Name -ne 'SHA256SUMS.csv' |
Get-FileHash -Algorithm SHA256 |
Export-Csv -NoTypeInformation $manifest
Import-Csv $manifest | ForEach-Object {
$actual = (Get-FileHash -LiteralPath $_.Path -Algorithm SHA256).Hash
[pscustomobject]@{
File = Split-Path $_.Path -Leaf
Verified = ($actual -eq $_.Hash)
}
}
❯ View Expected Console Output
File Verified
---- --------
collection-notes.txt True
defender-status.txt True
host.txt True
processes.csv True
recent-system-events.csv True
tcp-connections.csv True
udp-endpoints.csv True

Comments