Files
artif/windows/Get-RecentDocs.ps1
mnerv 878d19f917 Add Windows forensic artifact collection toolkit
Add PowerShell scripts for collecting forensic artifacts:
- USB/storage devices, mounted drives, portable devices
- Network history and hotspot connections
- Recent documents (OpenSavePidlMRU with PIDL parsing)
- System info and user enumeration with multiple output modes

Includes TODO.md for planned artifacts and updated README.
2026-02-03 21:31:39 +01:00

142 lines
5.1 KiB
PowerShell

# Get-RecentDocs.ps1
# Lists recently opened documents from OpenSavePidlMRU registry key
param(
[int]$MaxPerType = 10,
[switch]$ShowAll
)
Write-Host "=== Recently Opened Documents ===" -ForegroundColor Cyan
Write-Host "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSavePidlMRU"
if ($ShowAll) {
$MaxPerType = [int]::MaxValue
Write-Host "Showing all entries`n" -ForegroundColor Yellow
} else {
Write-Host "Showing top $MaxPerType per type (use -ShowAll or -MaxPerType N to see more)`n" -ForegroundColor Yellow
}
function Convert-PidlMRU {
param([byte[]]$data)
if (-not $data -or $data.Length -lt 10) {
return ""
}
try {
# Convert to Unicode string
$unicodeText = [System.Text.Encoding]::Unicode.GetString($data)
# Remove null characters
$cleaned = $unicodeText -replace '\x00', ''
# Try to extract valid file path (Windows path pattern)
if ($cleaned -match '([A-Z]:\\(?:[^<>:"|?*\x00-\x1F]+\\)*[^<>:"|?*\x00-\x1F\\]+)') {
return $matches[1]
}
# Extract filename - match only valid filename characters
# This regex looks for a sequence that starts with alphanumeric and includes a file extension
if ($cleaned -match '([a-zA-Z0-9][a-zA-Z0-9._\- ]{0,200}\.[a-zA-Z0-9]{1,10})') {
return $matches[1]
}
# Fallback: filter to printable ASCII only and look for pattern
$printable = -join ($cleaned.ToCharArray() | Where-Object {
($_ -ge 32 -and $_ -le 126)
})
# Try again with printable string
if ($printable -match '([a-zA-Z0-9][a-zA-Z0-9._\- ]{0,200}\.[a-zA-Z0-9]{1,10})') {
return $matches[1]
}
return ""
} catch {
return ""
}
}
try {
$mruPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSavePidlMRU"
if (Test-Path $mruPath) {
# Get all extension subkeys
$subKeys = Get-ChildItem -Path $mruPath -ErrorAction SilentlyContinue |
Sort-Object PSChildName
if ($subKeys) {
$totalFiles = 0
$totalStored = 0
foreach ($subKey in $subKeys) {
$extension = $subKey.PSChildName
$props = Get-ItemProperty -Path $subKey.PSPath -ErrorAction SilentlyContinue
# Get MRUListEx for ordering
if ($props.MRUListEx) {
$files = @()
for ($i = 0; $i -lt $props.MRUListEx.Length - 4; $i += 4) {
$index = [BitConverter]::ToInt32($props.MRUListEx, $i)
if ($index -eq -1) { break }
$propName = "$index"
if ($props.$propName) {
$fileName = Convert-PidlMRU -data $props.$propName
if ($fileName) {
$files += $fileName
}
}
}
$totalStored += $files.Count
# Only show if we found files
if ($files.Count -gt 0) {
if ($extension -eq "*") {
Write-Host "`n--- All File Types ($($files.Count) total) ---" -ForegroundColor Yellow
} else {
Write-Host "`n--- .$extension Files ($($files.Count) total) ---" -ForegroundColor Yellow
}
$count = 0
$displayFiles = $files | Select-Object -First $MaxPerType
foreach ($file in $displayFiles) {
$count++
$totalFiles++
Write-Host " $count. $file" -ForegroundColor Green
}
if ($files.Count -gt $MaxPerType) {
$remaining = $files.Count - $MaxPerType
Write-Host " ... and $remaining more" -ForegroundColor Gray
}
}
}
}
Write-Host "`n=== Summary ===" -ForegroundColor Cyan
Write-Host "Total stored: $totalStored files" -ForegroundColor Green
Write-Host "Displayed: $totalFiles files" -ForegroundColor Green
if ($totalFiles -eq 0) {
Write-Host "`nNo readable file paths found in MRU data" -ForegroundColor Gray
Write-Host "The PIDL binary format may require more advanced parsing" -ForegroundColor Gray
}
} else {
Write-Host "`nNo recent file history found" -ForegroundColor Gray
}
} else {
Write-Host "`nOpenSavePidlMRU registry key not found" -ForegroundColor Gray
}
} catch {
Write-Host "Error: $_" -ForegroundColor Red
}
Write-Host "`nNote: PIDL data parsing is limited. For complete analysis, use forensic tools like Registry Explorer" -ForegroundColor Cyan