PowerShell Compare-Hash Function

Quite some time ago I created a PowerShell function which allowed one to compare a given cryptographic hash against one locally generated to see if they match. Looking back on the old version (here is a link to the blog article https://www.bytesizedalex.com/powershell-cryptographic-hash-checker/) it is very much reminiscent of old school batch files. I decided now I am more familiar with PowerShell function creation it would be a good idea to take a second go at it.

I’ve added this version to my GitHub repository – https://github.com/bytesizedalex/compare-hash

The function is pretty simple and leverages the existing Get-FileHash cmdlet to generate the cryptographic hash. All I’ve done is add a comparison so you can provide the hash you have against the one it generates. The function will simply state ‘MATCH’ or ‘NO MATCH’ to indicate if they are the same or not, I find this handy when I want to check a download or copied file.

PowerShell Compare-Hash Function Examples

function Compare-Hash {
    <#
    .SYNOPSIS
    Compares a provided cryptographic hash against a generated one.
    .DESCRIPTION
    Used to compare a provided cryptographic hash against one locally generated for the target file. This is useful to ensure the file has not been altered or corrupted from the original. Updatesand additional information can be found at either https://github.com/bytesizedalex/compare-hash or on my blog https://www.bytesizedalex.com
    .EXAMPLE
    PS C:\> Compare-Hash -Algorithm MD5 -Hash '0CBC6611F5540BD0809A388DC95A615B' -Path C:\Test.txt
    MATCH
    .EXAMPLE
    PS C:\> Compare-Hash -Algorithm MD5 -Hash '123456' -Path C:\Test.txt
    NO MATCH
    .INPUTS
    Takes 3 string values:
    
    Algorithm: the desired cryptographic hash, e.g MD5 or SHA256
    Hash: the hash value provided and used to validate our output
    Path: a file path
 
    .OUTPUTS
    The command outputs a System.String value of 'MATCH' or 'NO MATCH' to indicate whether the hash values are equal.
    .PARAMETER Algorithm
    The cryptographic hash algorithm to be used.
    .PARAMETER Hash
    A provided hash to compare against the generated hash.
    .PARAMETER Path
    The file path to the file to be hash checked.
    #>
 
 
    [CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Low', HelpUri = 'https://github.com/bytesizedalex/compare-hash')]
    [OutputType([string])]
    [Alias()]
 
    Param (
 
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = 'Select a cryptographic hash - e.g MD5, SHA1, SHA256, SHA384 or SHA512')]
        [ValidateNotNull()]
        [ValidateNotNullOrEmpty()]
        [ValidateSet("MD5", "SHA1", "SHA256", "SHA384", "SHA512")]
        [string]$Algorithm,
 
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = 'Enter the provided cryptographic hash to validate against.')]
        [ValidateNotNull()]
        [ValidateNotNullOrEmpty()]
        [string]$Hash,
 
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = 'Enter the file path.')]
        [ValidateNotNull()]
        [ValidateNotNullOrEmpty()]
        [string]$Path
 
    )
 
    Begin {
 
        Write-Verbose -Message 'Clearing variables'
        Clear-Variable ComputedHash -ErrorAction SilentlyContinue
 
    }
 
    Process {
 
        Write-Verbose -Message 'Generating hash for selected file'
        $ComputedHash = (Get-FileHash -Algorithm $Algorithm -Path $Path -ErrorAction Stop).Hash
 
        Write-Verbose -Message 'Running if/else match loop'
        if ($ComputedHash -eq $Hash) {
 
            Write-Output 'MATCH'
 
        }
 
        else {
 
            Write-Output 'NO MATCH'
 
        }
 
    }
 
    End {
 
    }
 
}

I find it really interesting to look back on something I wrote nearly two years ago, I feel like this new version is certainly an improvement and something I’m much happier with.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.