Last active
November 24, 2020 08:15
-
-
Save iOnline247/77e9f1986536342a26a0db5a6bd89c51 to your computer and use it in GitHub Desktop.
Compare checksum of files or directories.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function logMsg($text, $color = [System.ConsoleColor]::green) { | |
Write-Host $text -foregroundcolor $color | |
Write-Host "`r`n" | |
} | |
<# | |
function Remove-DirectoryPathInfo ($fileInfo) { | |
$fileInfo.Path = $fileInfo.Path -replace "$([Regex]::Escape($testFiles[0].Parent.Parent.FullName))\\", "" | |
$fileInfo.Path = $fileInfo.Path -replace "$([Regex]::Escape($initialFiles[0].Parent.Parent.FullName))\\", "" | |
# "$([Regex]::Escape($parentDirectoryPath))\\" | |
# "$([Regex]::Escape($parentDirectoryPath+'\'))" | |
return $fileInfo | |
} | |
#> | |
function Get-Checksum { | |
param( | |
[Parameter(ValueFromPipeline = $true)] | |
$files, | |
[string[]]$ChecksumLogsPath = $null, | |
[ValidateSet("MD5", "SHA1", "SHA256", "SHA384", "SHA512", "RIPEMD160", "MACTripleDES")] | |
[string]$Algorithm = ("MD5", "SHA1", "SHA256", "SHA384", "SHA512", "RIPEMD160", "MACTripleDES") | |
) | |
BEGIN { | |
function getFormattedFileHash ($filePath, $Algorithm) { | |
$parentDirectoryPath = $file.DirectoryName | |
return Get-FileHash -LiteralPath $file.FullName -Algorithm $Algorithm | Select Hash, @{Name = 'FileName'; Expression = {$_.Path -replace "$([Regex]::Escape($parentDirectoryPath))\\", ""}} | |
} | |
$time = get-date | |
$logFile = $($env:userprofile + "\checkSum-" + $time.ticks + ".log") | |
} | |
PROCESS { | |
$files = $files | Where-Object { !$_.PSIsContainer } | |
foreach ($file in $files) { | |
$fileDeets = getFormattedFileHash -file $file -Algorithm $Algorithm | |
($fileDeets | Out-String).Trim() >> $logFile | |
} | |
} | |
END { | |
logMsg $("The checksum logfile was created: " + $logFile) | |
# Invoke-Item $logFile | |
return $logFile | |
} | |
} | |
function Compare-Checksum ($checksumLogPaths) { | |
logMsg "Generating hashes for each log file and comparing to the newly generated log hash..." | |
# Leave the .Trim() otherwise .Equals comparison doesn't work properly. | |
$checksumHashes = [psobject]@(); | |
foreach ($checksumLog in $checksumLogPaths) { | |
# Does checksum log exist? | |
$logExists = Test-Path $checksumLog | |
if (!$logExists) { | |
logMsg "This log file doesn't exist: $($checksumLog)" ([System.ConsoleColor]::red) | |
continue; | |
} | |
# Verify checksums | |
# Leave the .Trim() otherwise .Equals comparison doesn't work properly. | |
$checksumHash = (Get-FileHash -LiteralPath $checksumLog -Algorithm SHA512 | Select-Object Hash).Hash | |
$checksumHashes += $checksumHash | |
Write-Host "Hash for $($checksumLog):" -ForegroundColor Green | |
Write-Host "$checksumHash`r`n" -BackgroundColor Green | |
} | |
$isMatchingChecksums = @($checksumHashes | Select -Unique).Count -eq 1 | |
if ($isMatchingChecksums) { | |
logMsg "These checksums match.`r`n$checksumLogPaths`r`n`r`n" | |
} | |
else { | |
logMsg "These files are different:`r`n$checksumLogPaths`r`n$checksumHashes" ([System.ConsoleColor]::red) | |
} | |
} | |
try { | |
$initialPath = Read-Host -Prompt 'Give directory path...' | |
$testPath = Read-Host -Prompt 'Give path to test against...' | |
# C:\Users\mbramer\Documents\!src\infrastructure\ | |
$checksumLogPaths = @(); | |
$initialFiles = Get-ChildItem -Path $initialPath -Recurse | |
$testFiles = Get-ChildItem -Path $testPath -Recurse | |
$checksumLogPaths += ($initialFiles | Get-Checksum -Algorithm SHA256) | |
$checksumLogPaths += ($testFiles | Get-Checksum -Algorithm SHA256) | |
Compare-Checksum -checksumLogPaths $checksumLogPaths | |
} catch [Exception] { | |
Write-Error $_ | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Get-FileHashIndex | |
{ | |
<# | |
.Synopsis | |
Get File Hash for PowerShell V3 and Higher | |
.DESCRIPTION | |
Bringed C# how we retrieve File Hash to PowerShell Script. | |
This works equivalent to Get-FileHash (v4) but twice as faster and supports -Recurse switch. | |
measure-Command {Get-FileHashIndex -Path d:\test\test -Algorithm MACTripleDES -Recurse} # 684.4821 | |
measure-Command {Get-FileHashIndex -Path d:\test\test -Algorithm MD5 -Recurse} # 631.5687 | |
measure-Command {Get-FileHashIndex -Path d:\test\test -Algorithm RIPEMD160 -Recurse} # 693.6726 | |
measure-Command {Get-FileHashIndex -Path d:\test\test -Algorithm SHA1 -Recurse} # 641.9092 | |
measure-Command {Get-FileHashIndex -Path d:\test\test -Algorithm SHA256 -Recurse} # 695.2601 | |
measure-Command {Get-FileHashIndex -Path d:\test\test -Algorithm SHA384 -Recurse} # 677.8795 | |
measure-Command {Get-FileHashIndex -Path d:\test\test -Algorithm SHA512 -Recurse} # 685.4792 | |
measure-Command {ls d:\test\test -Recurse -File | Get-FileHashIndex -Algorithm MD5} # 878.1032 | |
measure-Command {ls d:\test\test -Recurse -File | Get-FileHash -Algorithm MD5} # 1364.2046 | |
measure-Command {ls d:\test\test -Recurse -File | Get-FileHash -Algorithm SHA256} # 1488.3237 | |
.EXAMPLE | |
PS > Get-FileHashIndex -Path d:\test\test -Algorithm MACTripleDES -Recurse | |
Algorythm Hash Path | |
--------- ---- ---- | |
MACTripleDES 40C3FEAAA71C928B2FC3D248F4DA86211FBC1726 D:\test\test\README.md | |
MACTripleDES 5DCE5F942594C97A9929D18507FB043FC23B917B D:\test\test\hoge\Thumbs.db | |
.EXAMPLE | |
PS > Get-FileHashIndex -Path d:\test\test -Algorithm MACTripleDES | |
Algorythm Hash Path | |
--------- ---- ---- | |
MACTripleDES 40C3FEAAA71C928B2FC3D248F4DA86211FBC1726 D:\test\test\README.md | |
.EXAMPLE | |
PS > Get-FileHashIndex -Path d:\test\test -Algorithm MD5 | |
Algorythm Hash Path | |
--------- ---- ---- | |
MD5 7C865A164CE6DFC4AE0E61EED9A49B8E D:\test\test\README.md | |
.EXAMPLE | |
PS > Get-FileHashIndex -Path d:\test\test -Algorithm RIPEMD160 | |
Algorythm Hash Path | |
--------- ---- ---- | |
RIPEMD160 92DD18916AA074B0931E63D14541C44F07783CDF D:\test\test\README.md | |
.EXAMPLE | |
PS > Get-FileHashIndex -Path d:\test\test -Algorithm SHA1 | |
Algorythm Hash Path | |
--------- ---- ---- | |
SHA1 73A0294775D3A91F1EC91EEF58AD28C48A5B515A D:\test\test\README.md | |
.EXAMPLE | |
PS > Get-FileHashIndex -Path d:\test\test -Algorithm SHA256 | |
Algorythm Hash Path | |
--------- ---- ---- | |
SHA256 50DB8AFF8EFE10C9CBAAA2BE941E841AFF5ECC... D:\test\test\README.md | |
.EXAMPLE | |
PS > Get-FileHashIndex -Path d:\test\test -Algorithm SHA384 | |
Algorythm Hash Path | |
--------- ---- ---- | |
SHA384 A8E66530035B84816C4C8BD2D4E17CC00D5848... D:\test\test\README.md | |
.EXAMPLE | |
PS > Get-FileHashIndex -Path d:\test\test -Algorithm SHA512 | |
Algorythm Hash Path | |
--------- ---- ---- | |
SHA512 13A29B1D0C28ED69B441481282B3983F729D51... D:\test\test\README.md | |
.OUTPUTS | |
[PSCustomObject] | |
Incluide Algorithm, Hash and Path Property | |
#> | |
[CmdletBinding()] | |
param | |
( | |
[parameter(Mandatory = 1, Position = 0, ValueFromPipeline = 1, ValueFromPipelineByPropertyName =1)] | |
[Alias("PSPath", "LiteralPath")] | |
[string[]]$Path, | |
[parameter(Mandatory = 0, Position = 1, ValueFromPipelineByPropertyName =1, ParameterSetName = "MD5")] | |
[ValidateSet("MACTripleDES", "MD5", "RIPEMD160", "SHA1", "SHA256", "SHA384", "SHA512")] | |
[string]$Algorithm = "SHA256", | |
[parameter(Mandatory = 0, Position = 2, ValueFromPipelineByPropertyName =1)] | |
[switch]$Recurse | |
) | |
process | |
{ | |
foreach ($p in $Path){ $list.Add($p) } | |
} | |
end | |
{ | |
foreach ($l in $list){ Get-ChildItem -Path $l -File -Recurse:$Recurse | GetHashInfo } | |
} | |
begin | |
{ | |
$list = New-Object 'System.Collections.Generic.List[string]' | |
filter GetHashInfo | |
{ | |
try | |
{ | |
[System.IO.FileStream]$stream = [System.IO.File]::OpenRead($_.fullname) | |
$hash = GetHash -Stream $stream -Algorithm $Algorithm | |
} | |
finally | |
{ | |
$stream.Dispose() | |
} | |
return [PSCustomObject]@{ | |
Algorithm = $Algorithm | |
Hash = $hash | |
Path = $_.FullName | |
File = $_ | |
} | |
} | |
function GetHash ([System.IO.FileStream]$Stream, [string]$Algorithm) | |
{ | |
try | |
{ | |
$crypto = [System.Security.Cryptography.HashAlgorithm]::Create($Algorithm) | |
[byte[]]$hash = $crypto.ComputeHash($Stream) | |
return [System.BitConverter]::ToString($hash).Replace("-", [string]::Empty) | |
} | |
finally | |
{ | |
$crypto.Dispose() | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment