Acquire Triage Data Using Powershell

1. Preparation

  • Launch PowerShell: Open PowerShell as Administrator (powershell.exe or pwsh.exe for PowerShell Core). Right-click the Start menu > "Windows PowerShell (Admin)" or use Run > PowerShell > Ctrl+Shift+Enter.

  • Set Output Location: Define a directory for triage data (e.g., local drive or external USB). Create it with:

    $OutputPath = "D:\TriageOutput"
    New-Item -Path $OutputPath -ItemType Directory -Force
  • Execution Policy: Check with Get-ExecutionPolicy. If restricted (Restricted), bypass it temporarily:

    Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass -Force
  • Logging: Start a transcript to log commands and output:powershell

    Start-Transcript -Path "$OutputPath\PowerShellTranscript.txt"

2. Define Triage ObjectivesFor effective triage, collect artifacts that reveal system state, user activity, potential persistence, and compromise indicators:

  • System info (OS, hardware, users)

  • Running processes and services

  • Network activity (connections, DNS, ARP)

  • Event logs (system, security, application)

  • Registry (persistence, configuration)

  • Filesystem (recent files, prefetch, temp)

  • Scheduled tasks and accounts

3. Comprehensive Collection ScriptBelow is a detailed PowerShell script (Triage.ps1) to collect these artifacts. Copy this into a .ps1 file or run commands individually.

# Define output directory and timestamp
$OutputPath = "D:\TriageOutput"
$Timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
New-Item -Path $OutputPath -ItemType Directory -Force

# Start logging
Start-Transcript -Path "$OutputPath\TriageTranscript_$Timestamp.txt"

# --- System Information ---
Write-Host "Collecting system information..."
Get-ComputerInfo | Export-Csv -Path "$OutputPath\SystemInfo_$Timestamp.csv" -NoTypeInformation
Get-WmiObject Win32_OperatingSystem | Select-Object Caption, Version, InstallDate, LastBootUpTime | Export-Csv -Path "$OutputPath\OSDetails_$Timestamp.csv" -NoTypeInformation
Get-WmiObject Win32_LoggedOnUser | Select-Object Antecedent, Dependent | Export-Csv -Path "$OutputPath\LoggedOnUsers_$Timestamp.csv" -NoTypeInformation

# --- Processes and Services ---
Write-Host "Collecting process and service data..."
Get-Process | Select-Object Name, Id, Path, StartTime, Company, CPU, Handles | Export-Csv -Path "$OutputPath\Processes_$Timestamp.csv" -NoTypeInformation
Get-WmiObject Win32_Process | Select-Object Name, ProcessId, CommandLine, CreationDate, ParentProcessId | Export-Csv -Path "$OutputPath\ProcessDetails_$Timestamp.csv" -NoTypeInformation
Get-Service | Select-Object Name, DisplayName, Status, StartType | Export-Csv -Path "$OutputPath\Services_$Timestamp.csv" -NoTypeInformation

# --- Network Activity ---
Write-Host "Collecting network data..."
Get-NetTCPConnection | Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort, State, OwningProcess, CreationTime | Export-Csv -Path "$OutputPath\NetConnections_$Timestamp.csv" -NoTypeInformation
Get-NetUDPEndpoint | Select-Object LocalAddress, LocalPort, OwningProcess | Export-Csv -Path "$OutputPath\UDPEndpoints_$Timestamp.csv" -NoTypeInformation
Get-NetNeighbor | Select-Object IPAddress, LinkLayerAddress, State | Export-Csv -Path "$OutputPath\ARPCache_$Timestamp.csv" -NoTypeInformation
Get-DnsClientCache | Select-Object Entry, Data, TimeToLive | Export-Csv -Path "$OutputPath\DNSCache_$Timestamp.csv" -NoTypeInformation
netstat -anob | Out-File -FilePath "$OutputPath\Netstat_$Timestamp.txt"

# --- Event Logs ---
Write-Host "Collecting event logs..."
$EventLogs = @("System", "Security", "Application")
foreach ($log in $EventLogs) {
    Get-WinEvent -LogName $log -MaxEvents 5000 -ErrorAction SilentlyContinue | Select-Object TimeCreated, Id, LevelDisplayName, Message | Export-Csv -Path "$OutputPath\$log`Events_$Timestamp.csv" -NoTypeInformation
}

# --- Registry Data ---
Write-Host "Collecting registry data..."
$RegPaths = @(
    "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:\System\CurrentControlSet\Services"
)
foreach ($path in $RegPaths) {
    $FileName = ($path -replace "[:\\]", "_") + "_$Timestamp.csv"
    Get-ItemProperty -Path $path -ErrorAction SilentlyContinue | Export-Csv -Path "$OutputPath\$FileName" -NoTypeInformation
}
reg export HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall "$OutputPath\InstalledSoftware_$Timestamp.reg" /y 2>$null

# --- File System Artifacts ---
Write-Host "Collecting filesystem artifacts..."
# Recent files (last 7 days)
Get-ChildItem -Path "C:\" -Recurse -File -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-7) } | Select-Object FullName, LastWriteTime, CreationTime, Length | Export-Csv -Path "$OutputPath\RecentFiles_$Timestamp.csv" -NoTypeInformation
# Prefetch files
New-Item -Path "$OutputPath\Prefetch" -ItemType Directory -Force
Copy-Item -Path "C:\Windows\Prefetch\*.pf" -Destination "$OutputPath\Prefetch" -ErrorAction SilentlyContinue
# Temp files
Get-ChildItem -Path "$env:TEMP" -Recurse -ErrorAction SilentlyContinue | Select-Object FullName, LastWriteTime | Export-Csv -Path "$OutputPath\TempFiles_$Timestamp.csv" -NoTypeInformation

# --- Scheduled Tasks ---
Write-Host "Collecting scheduled tasks..."
Get-ScheduledTask | Where-Object { $_.State -ne "Disabled" } | Select-Object TaskName, TaskPath, State, Actions | Export-Csv -Path "$OutputPath\ScheduledTasks_$Timestamp.csv" -NoTypeInformation
schtasks /query /fo csv /v | Out-File -FilePath "$OutputPath\ScheduledTasksDetailed_$Timestamp.csv"

# --- User Accounts ---
Write-Host "Collecting user account data..."
Get-LocalUser | Select-Object Name, Enabled, LastLogon, PasswordLastSet | Export-Csv -Path "$OutputPath\LocalUsers_$Timestamp.csv" -NoTypeInformation
net user | Out-File -FilePath "$OutputPath\NetUsers_$Timestamp.txt"

# --- Compress Output ---
Write-Host "Compressing triage data..."
Compress-Archive -Path "$OutputPath\*" -DestinationPath "D:\TriageData_$Timestamp.zip" -Force

# Stop logging
Stop-Transcript
Write-Host "Triage data collection complete. Output saved to D:\TriageData_$Timestamp.zip"

4. Execute the Collection

  • Run the Script: Save as Triage.ps1 and execute:powershell

    .\Triage.ps1
  • Alternative: Copy-paste commands into an admin PowerShell session or run individually.

  • Duration: Takes 5-20 minutes depending on system size, event log volume, and filesystem recursion depth.

5. Verify and Analyse

  • Output Check: Inspect $OutputPath for:

    • CSV files (e.g., Processes_20250226_123456.csv)

    • Text files (e.g., Netstat_20250226_123456.txt)

    • Exported files (e.g., Prefetch folder, .reg files)

    • ZIP archive (e.g., TriageData_20250226_123456.zip)

  • Analysis Tools:

    • CSVs: Open in Excel or import with Import-Csv for filtering.

    • Prefetch: Use PEcmd or forensic suites (Autopsy, FTK).

    • Event Logs: Parse with Event Log Explorer or custom scripts.

    • Registry: Import .reg files or analyse CSVs in RegRipper.

6. Advanced Enhancements

  • Memory Dump: Pair with DumpIt or winpmem for RAM capture (PowerShell can’t do this natively):

    Start-Process -FilePath "C:\Tools\DumpIt.exe" -ArgumentList "/O $OutputPath\MemoryDump_$Timestamp.raw" -Wait
  • Hash Files: Add MD5 hashes for integrity:

    Get-ChildItem "$OutputPath\Prefetch" | Get-FileHash -Algorithm MD5 | Export-Csv "$OutputPath\PrefetchHashes_$Timestamp.csv" -NoTypeInformation
  • Remote Execution: Run on networked systems:

    Invoke-Command -ComputerName TARGET-PC -FilePath .\Triage.ps1 -Credential (Get-Credential)

7. Tips and Considerations

  • Scope Control: Adjust -MaxEvents (e.g., 5000 to 1000) or file search depth to speed up collection.

  • Error Handling: ErrorAction SilentlyContinue skips inaccessible areas (e.g., locked files).

  • Live Only: For forensic images, mount them first (e.g., via Arsenal Image Mounter) and adjust paths.

  • Stealth: Use a USB or remote session to minimise footprint; avoid writing to C: if possible.

  • Permissions: Admin rights are required for most cmdlets (e.g., Get-WinEvent, Get-ScheduledTask).

Last updated