Skip to content

Instantly share code, notes, and snippets.

@Qazeer
Created July 8, 2023 13:56
Show Gist options
  • Save Qazeer/cb3a0cf306bc1f75a2d5a8cef5b9ffa9 to your computer and use it in GitHub Desktop.
Save Qazeer/cb3a0cf306bc1f75a2d5a8cef5b9ffa9 to your computer and use it in GitHub Desktop.
Recursively process the specified input folder to execute thumbcache_viewer_cmd.exe over each thumbcache subfolder(s) found.
<#
.SYNOPSIS
Recursively process the specified input folder to execute thumbcache_viewer_cmd.exe over each thumbcache subfolder(s) found.
This PowerShell script is basically a wrapper to make thumbcache_viewer_cmd.exe recursive, as the tool can natively only process a thumbcache subfolder
(and not multiple thumbcache subfolder(s) from the drive root or user profile folders).
Script inspired by the Move-KAPEConsoleHost_history.ps1 script from Andrew Rathbun and Matt Arbaugh: https://github.com/AndrewRathbun/DFIRPowerShellScripts/blob/main/Move-KAPEConsoleHost_history.ps1
.PARAMETER thumbcacheViewerBinary
Specify the thumbcache_viewer_cmd.exe binary full path.
.PARAMETER InputDir
Specify the folder which contains the thumbcache_*.db file(s). Ideally, the C:\ or C:\Users|Utilisateurs|Usuarios|Benutzer directory in order to grab the file(s) from all users.
.PARAMETER OutputDir
Specify the folder where the ThumbcacheViewer output will be placed.
#>
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true,
Position = 1,
HelpMessage = 'Specify the thumbcache_viewer_cmd.exe binary full path.')]
[String]$thumbcacheViewerBinary,
[Parameter(Mandatory = $true,
Position = 2,
HelpMessage = 'Specify the folder which contains the thumbcache_*.db file(s). Ideally, the C:\ or C:\Users|Utilisateurs|Usuarios|Benutzer directory in order to grab the file(s) from all users.')]
[String]$InputDir,
[Parameter(Mandatory = $true,
Position = 3,
HelpMessage = 'Specify the folder where the ThumbcacheViewer outputs will be placed.')]
[String]$OutputDir
)
try {
# Check if $thumbcacheViewerBinary exists.
if (-not (Test-Path -Path $thumbcacheViewerBinary -PathType Leaf)) {
throw "The $thumbcacheViewerBinary binary does not exist."
}
# Check if $InputDir exists.
if (-not (Test-Path -Path $InputDir -PathType Container)) {
throw "The directory $InputDir does not exist."
}
# Create the $OutputDir path if it does not exist.
if (-not (Test-Path -Path $OutputDir -PathType Container)) {
# Create the directory, but do not prompt for confirmation (-Confirm:$false).
[void] (New-Item -ItemType Directory -Path $OutputDir -Confirm:$false)
}
# Regex pattern to extract username from file path.
$usernameRegex = "\\(Users|Utilisateurs|Usuarios|Benutzer)\\(.+?)\\AppData\\"
# Look for thumbcache_*.db files in $InputDir.
$thumbcacheDBTxt = 'thumbcache_*.db'
$files = Get-ChildItem -Path $InputDir -Filter $thumbcacheDBTxt -Recurse -ErrorAction Stop
# Retrieve the folder(s) containg thumbcache_*.db files, in a set to only retrieve each folder once.
$thumbcacheFolders = New-Object System.Collections.Generic.HashSet[string]
foreach ($file in $files) {
$null = $thumbcacheFolders.Add($file.Directory)
}
# Check if files and folders were found
if ($null -eq $files -or $files.Count -eq 0) {
Write-Host "No $thumbcacheDBTxt file(s) were found in $InputDir"
}
else {
Write-Host "Found $($files.Count) $thumbcacheDBTxt file(s) accross $($thumbcacheFolders.Count) directories in $InputDir"
}
# Parse the thumbcache_*.db from each folders, one folder by one folder.
foreach ($thumbcacheFolder in $thumbcacheFolders) {
$folderItem = Get-Item $thumbcacheFolder
# Extract username from file path.
$folderItem -match $usernameRegex | Out-Null
$username = $matches[2]
# Output folder, specific for each user.
$outputPath = $([IO.Path]::Combine($OutputDir, "Thumcache_$username"))
if (-not (Test-Path -Path $outputPath -PathType Container)) {
[void] (New-Item -ItemType Directory -Path $outputPath -Confirm:$false)
}
Start-Process -NoNewWindow -Wait $thumbcacheViewerBinary -ArgumentList "-o $outputPath -w -c -z -d $thumbcacheFolder" -RedirectStandardOutput "$(Join-Path $OutputPath "ThumbcacheViewer_stdout.log")" -RedirectStandardError "$(Join-Path $OutputPath "ThumbcacheViewer_stderr.log")"
}
}
catch [System.Exception] {
# If an error occurred, print error details
Write-Error "An error occurred while running this script"
Write-Error "Exception type: $($_.Exception.GetType().FullName)"
Write-Error "Exception message: $($_.Exception.Message)"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment