Skip to content

Instantly share code, notes, and snippets.

@ghotz
Last active May 5, 2025 21:37
Show Gist options
  • Save ghotz/0ef1cdcce3025e5d2f165a2ad4bfa7d7 to your computer and use it in GitHub Desktop.
Save ghotz/0ef1cdcce3025e5d2f165a2ad4bfa7d7 to your computer and use it in GitHub Desktop.
Scan and repair PSTs with multiple passes and full PST amd log archival
$scanPSTExe = "C:\Program Files\Microsoft Office\root\Office16\SCANPST.EXE"
$SourceDir = "E:\Outlook\test"
$BackupDir = "F:\Backups\Outlook\test"
$MaxIterations = 10
$PSTs = Get-ChildItem -Path (Join-Path $SourceDir "\*") -Include *.pst,*.ost -File
$PSTs | ForEach-Object {
$NumIteration = 1
while ($NumIteration -le $MaxIterations) {
# Run SCANPST.EXE to repair the PST file
if ($NumIteration -eq 1) {
$PSTFileBackupName = Join-path $BackupDir ("{0}.{1}{2}.bak" -f $_.BaseName, (Get-Date -Format "yyyyMMddHHmmss"), $_.Extension)
} else {
$PSTFileBackupName = ""
}
Write-Host "Running SCANPST.EXE on $($_.FullName) (iteration $NumIteration)"
& $scanPSTExe -file $_.FullName -Repair -log replace -BackupFile $PSTFileBackupName -rescan 10 -force
# Because scanpst.exe detaches from the console, we need to wait for it to finish
while ($true) {
$process = Get-Process -Name "SCANPST" -ErrorAction SilentlyContinue
if ($process) {
Write-Verbose "Waiting for SCANPST.EXE to finish..."
Start-Sleep -Seconds 1
} else {
break
}
}
# Move the log file to the backup directory
$CurrentLog = (Join-path $_.DirectoryName ("{0}.log" -f $_.BaseName))
$ArchivedLog = (Join-Path $BackupDir ("{0}.{1}.log" -f $_.BaseName, (Get-Date -Format "yyyyMMddHHmmss")))
try {
Copy-Item -Path $CurrentLog -Destination $ArchivedLog -ErrorAction Stop -Force
} catch {
Write-Warning "Failed to archive log file"
}
# Check the log file for errors
$Errors = Select-String -Path $CurrentLog -SimpleMatch '!!','??','Failed'
if ($errors) {
$NumIteration++
}
else {
break;
}
}
# This script will scan and repair all PST files in the specified directory and its subdirectories.
if ($NumIteration -gt $MaxIterations) {
Write-Host "Reached maximum iterations for $($_.FullName). Please check the log file for details."
} else {
Write-Host "Repair completed successfully for $($_.FullName)."
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment