Skip to content

Instantly share code, notes, and snippets.

@cgranade
Last active May 15, 2018 14:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cgranade/f7187fb1ba1e9beed1e1efa5b1ae02b0 to your computer and use it in GitHub Desktop.
Save cgranade/f7187fb1ba1e9beed1e1efa5b1ae02b0 to your computer and use it in GitHub Desktop.
[CmdletBinding(
SupportsShouldProcess = $true,
ConfirmImpact = "High"
)]
param(
[string]
$GoodDirectory,
[string]
$TargetDirectory
);
@"
Comparing:
$GoodDirectory
to:
$TargetDirectory
"@ | Write-Host;
$actualGood = (Resolve-Path -LiteralPath $GoodDirectory);
$actualTarget = (Resolve-Path -LiteralPath $TargetDirectory);
Push-Location $GoodDirectory
$goodHashes = @{};
$filesInGood = Get-ChildItem -File -Recurse -LiteralPath $actualGood `
| Where-Object { -not $_.PSIsContainer } `
| ForEach-Object {
Resolve-Path -Relative -LiteralPath $_.FullName
};
$filesInGood | ForEach-Object {
$prog = $goodHashes.Count / $filesInGood.Length;
Write-Progress -Activity "Hashing good directory..." -Status "$prog" -PercentComplete (100 * $prog);
$goodHashes.Add($_, (Get-FileHash -LiteralPath $_ -Algorithm SHA256).Hash);
};
Pop-Location
Push-Location $TargetDirectory
$filesInTarget = Get-ChildItem -File -Recurse -LiteralPath $actualTarget `
| Where-Object { -not $_.PSIsContainer } `
| ForEach-Object { Resolve-Path -Relative -LiteralPath $_.FullName }
"${$filesInTarget.Length} files in target directory." | Write-Host;
$nTargetFilesProcessed = 0;
$filesSafelyInTarget = $filesInTarget `
| Where-Object {
$prog = $nTargetFilesProcessed / $filesInTarget.Length;
Write-Progress -Activity "Hashing target directory..." -Status "$prog" -PercentComplete (100 * $prog);
# First check if this filename is in the good hashes or not.
if ($goodHashes.ContainsKey($_)) {
# Next, check that the hash was OK.
$goodHash = $goodHashes[$_];
$thisHash = (Get-FileHash -LiteralPath $_ -Algorithm SHA256).Hash;
if ($thisHash -eq $goodHash) {
$true | Write-Output;
} else {
"Hashes ${$thisHash} and ${$goodHash} for $_ did not match." | Write-Host;
$false | Write-Output;
}
} else {
$false | Write-Output;
}
$nTargetFilesProcessed += 1;
};
Pop-Location
"$($filesSafelyInTarget.Length) out of $($filesInGood.Length) safely in target." | Write-Host;
Push-Location $GoodDirectory
$nOriginalsDeleted = 0;
$filesSafelyInTarget | ForEach-Object {
$prog = $nOriginalsDeleted / $filesSafelyInTarget.Length;
Write-Progress `
-Activity "Deleting originals for files safely in target..." `
-Status "$prog" `
-PercentComplete (100 * $prog)
$itemToRemove = (Resolve-Path -LiteralPath $_ -ErrorAction SilentlyContinue);
if ($itemToRemove -and $PSCmdlet.ShouldProcess($itemToRemove)) {
Remove-Item -LiteralPath $itemToRemove;
}
$nOriginalsDeleted += 1;
}
Pop-Location
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment