Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compare Filehash in Powershell

I'm a powershell. I've been staring at my screen for most of the afternoon trying to figure out how to compare the file hash of multiple files that are in two different directories. The script will download files from an FTP site into a directory ($cDlPath) and eventually copy them to another directory ($cDestPath). I want to compare the filehash from the files to be sure nothing has changed since they were downloaded. I'm using the Get-Hash cmdlet to get the file hash, but I can't figure out how to compare the two hashes. If the files are unequal I want to be able to identify the altered file(s) by name so the files can be checked.

I've been fiddling around with the code below, but it doesn't seem to be what I'm after.

Compare-Object `
-ReferenceObject $(Get-ChildItem $cDestPath -Recurse | Where-Object {!$_.psiscontainer } | Get-Hash -Algorithm $cHashAlg) `
-DifferenceObject $(Get-ChildItem  $cDlPath -Recurse | Where-Object {!$_.psiscontainer } | Get-Hash -Algorithm $cHashAlg)

Any help would be greatly appreciated.


I'm using the code below and I seem to be a little closer.

Compare-Object $(Get-ChildItem $cDlPath -Recurse $_ | Where-Object { !$_.PsIsContainer } |  
  Select-Object Name, FullName, Length, @{Name=”SHA256 Hash”; Expression={ Get-Hash $_.FullName  
  -Algorithm "SHA256" }}, LastWriteTime) $( Get-ChildItem $cDestPath -Recurse $_ | Where-Object  
  { !$_.PsIsContainer } | Select-Object Name, FullName, Length, @{Name=”SHA256 Hash”; 
  Expression={ Get-Hash $_.FullName -Algorithm "SHA256" }}, LastWriteTime) -property @
  ("Name", “FullName”,”SHA256 Hash”, "Length", "LastWriteTime" ) | Add-Content -Path $cLogFile

It still looks like it isn't completely right though because there are some hashes that are the same and the output to the logfile is ugly. The files should only be in the log file if they have the same hash.

@{Name=nothing.xlsx; FullName=C:\Test\nothing.xlsx; SHA256 Hash=E74424B6324DE014CB0C896DA29D67A2A729E31DF57119E840CA4BD9A9E41754; Length=8891; LastWriteTime=7/31/2012 1:33:11 PM; SideIndicator=<=}
@{Name=test.txt; FullName=C:\Test\test.txt; SHA256 Hash=FC43E73579DB001751A29C1F7A8E2E36E46A53662B63013F0AE500AA896DE056; Length=174; LastWriteTime=7/31/2012 4:52:52 PM; SideIndicator=<=}
@{Name=testfile.txt; FullName=C:\Test\testfile.txt; SHA256 Hash=2B2DB80CAF93224A49A7C94E8EA5BCB1B86D421EA2DB83285149ECAE6DEAA105; Length=415; LastWriteTime=7/27/2012 12:01:21 PM; SideIndicator=<=}
@{Name=nothing.xlsx; FullName=C:\Test\Old\nothing.xlsx; SHA256 Hash=22603417927343A485862CE93790203EE7C2DB092C2060C92D44B736A01FD37E; Length=8978; LastWriteTime=7/31/2012 4:40:43 PM; SideIndicator=<=}
@{Name=test.txt; FullName=C:\Test\Old\test.txt; SHA256 Hash=FC43E73579DB001751A29C1F7A8E2E36E46A53662B63013F0AE500AA896DE056; Length=174; LastWriteTime=7/31/2012 4:52:52 PM; SideIndicator=<=}
@{Name=testfile.txt; FullName=C:\Test\Old\testfile.txt; SHA256 Hash=0B35A9F7F500B46469E2C1759F92D222983C4FDF4AAE316C0F2861FC70D0FD2B; Length=447; LastWriteTime=7/31/2012 4:52:40 PM; SideIndicator=<=}
like image 289
mack Avatar asked Jul 31 '12 18:07

mack


People also ask

What is get FileHash?

Description. The Get-FileHash cmdlet computes the hash value for a file by using a specified hash algorithm. A hash value is a unique value that corresponds to the content of the file.


2 Answers

I realize this is a stale thread (16 months old), but it was the top result in Google, which means it's getting a lot of views. I think this might benefit others...

Mack was right, there is a prettier & much simpler solution using Get-Hash. You can simply compare the hashes within the IF statement by comparing the Hash.

# Get the file hashes
$hashSrc = Get-FileHash $file -Algorithm "SHA256"
$hashDest = Get-FileHash $file2 -Algorithm "SHA256"

# Compare the hashes & note this in the log
If ($hashSrc.Hash -ne $hashDest.Hash)
{
  Add-Content -Path $cLogFile -Value " Source File Hash: $hashSrc does not 
  equal Existing Destination File Hash: $hashDest the files are NOT EQUAL."
}
like image 57
McFly Avatar answered Oct 07 '22 07:10

McFly


There has to be a prettier solution, but this is what I ended up using.

# Get the file hashes
$hashsourcefile = Get-Hash $file -Algorithm "SHA256"
$hashdestfile = Get-Hash $file2 -Algorithm "SHA256"

# Compare the hashes
Compare-Object -Referenceobject $hashsourcefile -Differenceobject $hashdestfile | % { If ($_.Sideindicator -ne " ==") {$diff+=1} }                  

# The Hashes are different. Note this in the log
if ($diff -ne 0)
{
    Add-Content -Path $cLogFile -Value " Source File Hash: $hashsourcefile does not equal 
    Existing Destination File Hash: $hashdestfile the files are NOT EQUAL."
}
like image 30
mack Avatar answered Oct 07 '22 07:10

mack