# Get-SearchHistory.ps1 # Extracts Windows Search history from WordWheelQuery registry param( [int]$MaxResults = 50, [switch]$ShowAll ) Write-Host "=== Windows Search History ===" -ForegroundColor Cyan Write-Host "Search queries from Windows Search Bar and File Explorer`n" Write-Host "Note: Windows 11 without Microsoft account may not persist search history" -ForegroundColor Yellow Write-Host "Modern search uses cloud sync and memory-only caching`n" -ForegroundColor Yellow if ($ShowAll) { $MaxResults = [int]::MaxValue } $foundAny = $false # WordWheelQuery - Windows Search history Write-Host "--- WordWheelQuery (Search Bar / File Explorer) ---" -ForegroundColor Yellow try { $wordWheelPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\WordWheelQuery" if (Test-Path $wordWheelPath) { $props = Get-ItemProperty -Path $wordWheelPath -ErrorAction SilentlyContinue # Get MRUListEx to determine order if ($props.MRUListEx) { $searches = @() # Parse MRUListEx (4-byte integers) for ($i = 0; $i -lt $props.MRUListEx.Length - 4; $i += 4) { $index = [BitConverter]::ToInt32($props.MRUListEx, $i) if ($index -eq -1) { break } # End marker # Get the search term from the indexed property $propName = "$index" if ($props.$propName) { # Convert binary data to Unicode string $searchTerm = [System.Text.Encoding]::Unicode.GetString($props.$propName) # Remove null terminators $searchTerm = $searchTerm -replace '\x00', '' if ($searchTerm) { $searches += $searchTerm } } } if ($searches.Count -gt 0) { $foundAny = $true Write-Host "Registry: $wordWheelPath`n" -ForegroundColor Gray $count = 0 foreach ($search in ($searches | Select-Object -First $MaxResults)) { $count++ Write-Host " $count. $search" -ForegroundColor Green } if ($searches.Count -gt $MaxResults) { Write-Host "`n ... and $($searches.Count - $MaxResults) more" -ForegroundColor Gray } Write-Host "`nTotal searches: $($searches.Count)" -ForegroundColor Green } else { Write-Host " No search history found" -ForegroundColor Gray } } else { Write-Host " No MRUListEx found" -ForegroundColor Gray } } else { Write-Host " Registry key not found" -ForegroundColor Gray } } catch { Write-Host " Error: $_" -ForegroundColor Red } # TypedPaths - File Explorer address bar typed paths Write-Host "`n--- TypedPaths (File Explorer Address Bar) ---" -ForegroundColor Yellow try { $typedPathsPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\TypedPaths" if (Test-Path $typedPathsPath) { $paths = Get-ItemProperty -Path $typedPathsPath -ErrorAction SilentlyContinue $pathList = @() # TypedPaths stores as url1, url2, etc. for ($i = 1; $i -le 50; $i++) { $urlKey = "url$i" if ($paths.$urlKey) { $pathList += $paths.$urlKey } } if ($pathList.Count -gt 0) { $foundAny = $true Write-Host "Registry: $typedPathsPath`n" -ForegroundColor Gray $count = 0 foreach ($path in ($pathList | Select-Object -First $MaxResults)) { $count++ Write-Host " $count. $path" -ForegroundColor Green } Write-Host "`nTotal typed paths: $($pathList.Count)" -ForegroundColor Green } else { Write-Host " No typed paths found" -ForegroundColor Gray } } else { Write-Host " Registry key not found" -ForegroundColor Gray } } catch { Write-Host " Error: $_" -ForegroundColor Red } # RunMRU - Run dialog history Write-Host "`n--- RunMRU (Run Dialog History) ---" -ForegroundColor Yellow try { $runMRUPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU" if (Test-Path $runMRUPath) { $runProps = Get-ItemProperty -Path $runMRUPath -ErrorAction SilentlyContinue $runList = @() # RunMRU uses letter keys (a, b, c, etc.) and MRUList for order if ($runProps.MRUList) { $mruOrder = $runProps.MRUList.ToCharArray() foreach ($char in $mruOrder) { $key = [string]$char if ($runProps.$key) { # Remove \1 terminator if present $command = $runProps.$key -replace '\\1$', '' if ($command) { $runList += $command } } } } if ($runList.Count -gt 0) { $foundAny = $true Write-Host "Registry: $runMRUPath`n" -ForegroundColor Gray $count = 0 foreach ($cmd in ($runList | Select-Object -First $MaxResults)) { $count++ Write-Host " $count. $cmd" -ForegroundColor Green } Write-Host "`nTotal run commands: $($runList.Count)" -ForegroundColor Green } else { Write-Host " No run history found" -ForegroundColor Gray } } else { Write-Host " Registry key not found" -ForegroundColor Gray } } catch { Write-Host " Error: $_" -ForegroundColor Red } # Recent searches in specific apps (if available) Write-Host "`n--- Cortana/Search App (if available) ---" -ForegroundColor Yellow try { # Check for modern search database $searchPackage = Get-ChildItem "$env:LOCALAPPDATA\Packages" -Filter "Microsoft.Windows.Search_*" -Directory -ErrorAction SilentlyContinue | Select-Object -First 1 if ($searchPackage) { $searchCache = Join-Path $searchPackage.FullName "LocalState\DeviceSearchCache" if (Test-Path $searchCache) { Write-Host " Search cache found: $searchCache" -ForegroundColor Cyan Write-Host " (Binary database - requires specialized tools to parse)" -ForegroundColor Yellow } else { Write-Host " Search cache not found" -ForegroundColor Gray } } else { Write-Host " Modern search app not found" -ForegroundColor Gray } } catch { Write-Host " Error: $_" -ForegroundColor Red } if (-not $foundAny) { Write-Host "`nNo search history found" -ForegroundColor Gray Write-Host "This is common on Windows 11 without a Microsoft account" -ForegroundColor Yellow } Write-Host "`nNote: Search history shows user queries and typed paths" -ForegroundColor Cyan Write-Host "This can reveal file names, apps, and topics of interest" -ForegroundColor Cyan Write-Host "`nWindows 11 Limitation: Modern search without Microsoft account" -ForegroundColor Yellow Write-Host "does not persist history to registry (cloud-first design)" -ForegroundColor Yellow Write-Host "This works best on Windows 10 or systems with Microsoft accounts" -ForegroundColor Yellow