Comparing Hashes in Powershell

Welcome Forums General PowerShell Q&A Comparing Hashes in Powershell

This topic contains 1 reply, has 2 voices, and was last updated by

 
Participant
4 weeks, 1 day ago.

  • Author
    Posts
  • #178632

    Participant
    Topics: 1
    Replies: 0
    Points: 13
    Rank: Member

    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 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

  • #178752

    Participant
    Topics: 1
    Replies: 1552
    Points: 2,700
    Helping Hand
    Rank: Community Hero

    ... Any ideas?

    Dave ... where should we start? 😉

    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. 😉

    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 ... 😉

    $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. 😉

    I hope you can use something from my ideas.

You must be logged in to reply to this topic.