Comparing Hashes in Powershell

Hi all,

 

So I am very new to powershell and have been asked to work on a little project here at work. We have a current script that takes your input <File location, file where to save, and saved file name> and takes the file location and hashes the files to sha56 and saves the file to a txt file. Below is the code. What I am looking to have happen is once the file is saved, I would like for a prompt to maybe ask “Do you want to compare this to another file?” and if you say yes, you input the location and name of the file and then compares the hash of that file to the one that was just created. Any ideas?

param([string]$titlehashlocation=“”,[string]$title2hashstorage=“”, [string]$sha256=“” )

Function hash{

if([string]::IsNullOrWhiteSpace($titlehashlocation))
{

write-host null or whitespace
exit

if(Test-Path -Path $titlehashlocation)

{

write-host “filepath is confirmed starting hashing of the files”

}

else

{

write-host “fliepath does not exist”

exit

}

}
else
{

if(Test-Path -Path $titlehashlocation)
{
write-host “filepath is confirmed starting hashing of the files”
}
else
{
write-host “fliepath does not exist”
exit
}
}

if([string]::IsNullOrWhiteSpace($title2hashstorage))
{

write-host storage value is null
exit
}

else
{

if([string]::IsNullOrWhiteSpace($sha256))
{
write-host ull value detected

}
else
{
$date = Get-Date
$dirend = “C:\pscript”
cd $titlehashlocation
gci $titlehashlocation.Split(‘.’) -Recurse | % {Get-FileHash $.Fullname } |Format-List > $title2hashstorage/$sha256
gci $titlehashlocation.Split(‘.’) -Recurse | % {Get-FileHash $
.Fullname } |Out-GridView
“-----------------------------------------------------------------------” >> $title2hashstorage/$sha256
“-----------------------------------------------------------------------” >> $title2hashstorage/$sha256
“-----------------------------------------------------------------------” >> $title2hashstorage/$sha256
“Hash Generated at $date” >> $title2hashstorage/$sha256

write-host “hashing is complete! :)”
cd $dirend
}
}

}

hash $titlehashlocation

Dave … where should we start? :wink:

Maybe first: you should format your code as code here in the forum (it’s described here: Read Me Before Posting! You’ll be Glad You Did!) and you should do yourself a favor and start formatting your code nicely. It makes it easier to read and easier to understand - not just for yourself. You might read The unofficial Powershell Best Practice and Style Guide.

Next you might re-think your task in general. What purpose do these hashes serve you collect? You know that it does not make any sense to compare hashes of files if their size does not match perfectly, right? Depending on the amount of data you process you create useless data at a considerable high technical cost.

Last but not least you might break up your code into smaller pieces. Create smaller functions serving only one purpose each and connect them with a controler script. So the smaller pieces are easier re-usable and easier to maintain or tweak if needed.

Just to show what I mean:

Let’s say you want to compare the file info of the files in two different folders and you want the user to be able to choose the folders. That’s what I usually try to avoid but if it’s nessecary I try to at least limit the choice of the user to some predefined options to limit errors I would have to deal with later on. :wink:

First we create the “helper functions”:

function Get-FileInfoByFolder {
    [CmdletBinding()]
    param(
        [Parameter(Position = 0, Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $Path
    )
    Get-ChildItem -Path $Path | ForEach-Object {
        $Hash = Get-FileHash -Path $_.FullName 
        [PSCustomObject]@{
            Name      = $_.Name
            FullName  = $_.FullName
            Length    = $_.Length
            Algorithm = $Hash.Algorithm
            Hash      = $Hash.Hash
        }
    }
}

function Select-Folder {
    [CmdletBinding()]
    [OutputType([string])]
    param(
        [System.String]
        $PreSelection = 'C:\temp'
    )
    Add-Type -AssemblyName System.Windows.Forms
    $FolderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog -Property @{
        SelectedPath = $PreSelection
    }
 
    [void]$FolderBrowser.ShowDialog()
    $FolderBrowser.SelectedPath 
}

function Select-File {
    param (
        [System.String]
        $Filter = 'Comma Seperated Value (*.csv)|*.csv|All files (*.*)|*.*',
        [System.String]
        $PreSelection = 'C:\temp'
    )
    Add-Type -AssemblyName System.Windows.Forms
    $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{
        Multiselect  = $false 
        Filter       = $Filter
        InitialDirectory = $PreSelection
    }

    [void]$FileBrowser.ShowDialog()
    $FileBrowser.FileName;
}

Now we can connect these helper functions with some meaningful and easy to read code:
First you select two dirrefent folders …

$Folder1 = Select-Folder -PreSelection 'D:\sample'
$Folder2 = Select-Folder -PreSelection 'C:\sample'

… then you create the actual data you need for the comparison …

$Result1 = Get-FileInfoByFolder -Path $Folder1
$Result2 = Get-FileInfoByFolder -Path $Folder2

… let’s safe it this time to the disk for later use …

$Result1 | Export-Csv -Path C:\temp\Result1.csv -NoTypeInformation
$Result2 | Export-Csv -Path C:\temp\Result2.csv -NoTypeInformation

… now we start our comparison process … first we choose two appropriate files …

$ReferenceData = Select-File 
$DifferenceData = Select-File

… now we compare the data contained in these files with the appropriate Powershell cmdlet that makes it easy to compare objects … :wink:

$Comparison = Compare-Object -ReferenceObject $ReferenceData -DifferenceObject $DifferenceData -Property Length -IncludeEqual 

… and we output it to the user …

$Comparison | Out-GridView

… of course we could safe it for later use or do any thinkable stuff with it because it is the pure data with no interpretation yet and no added arbitrary text like “——————” for example. :wink:

I hope you can use something from my ideas.