Skip to content

Instantly share code, notes, and snippets.

@drlsdee
Created September 19, 2024 05:46
Show Gist options
  • Save drlsdee/3d33dd859d9987428414ebfc8d14160f to your computer and use it in GitHub Desktop.
Save drlsdee/3d33dd859d9987428414ebfc8d14160f to your computer and use it in GitHub Desktop.
Compares the actual hash of a file with the specified reference value using the Get-FileHash cmdlet from the Microsoft.PowerShell.Utility module.
function Test-FileHash {
[CmdletBinding()]
[OutputType([bool])]
param (
[Parameter(Mandatory, ParameterSetName = 'Path',
Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
[ValidateNotNullOrEmpty()]
[ValidateScript({ [System.IO.File]::Exists($_) })]
[Alias('FullName')]
[string]$Path,
[Parameter(Mandatory, ParameterSetName = 'LiteralPath',
ValueFromPipelineByPropertyName)]
[ValidateNotNullOrEmpty()]
[ValidateScript({ [System.IO.File]::Exists($_) })]
[Alias('PSPath')]
[string]$LiteralPath,
[Parameter(Mandatory, ParameterSetName = 'InputStream',
ValueFromPipelineByPropertyName)]
[ValidateNotNullOrEmpty()]
[System.IO.Stream]$InputStream,
[Parameter(ParameterSetName = 'Path', Position = 1, ValueFromPipelineByPropertyName)]
[Parameter(Mandatory, ParameterSetName = 'LiteralPath')]
[Parameter(Mandatory, ParameterSetName = 'InputStream')]
[ValidateNotNullOrEmpty()]
[string]$Hash,
[Parameter(ParameterSetName = 'Path', Position = 2)]
[Parameter(ParameterSetName = 'LiteralPath')]
[Parameter(ParameterSetName = 'InputStream')]
[ValidateSet('SHA1', 'SHA256', 'SHA384', 'SHA512', 'MACTripleDES', 'MD5', 'RIPEMD160')]
[string]$Algorithm = 'SHA256'
)
begin {
[scriptblock]$sbReadHash = {
param (
[string]$filePath,
[string]$hashAlgo
)
[string]$hashPath = [System.IO.Path]::ChangeExtension($filePath, $hashAlgo.ToLowerInvariant())
if (-not [System.IO.File]::Exists($hashPath)) {
throw [System.IO.FileNotFoundException]::new(
"Cannot find the file with $hashAlgo hashsum", $hashPath
)
}
try {
[string[]]$hashRaw = [System.IO.File]::ReadAllLines(
$hashPath
).Where({
(-not [string]::IsNullOrEmpty($_)) -and (-not [string]::IsNullOrWhiteSpace($_))
})
}
catch {
[string[]]$hashRaw = @()
throw $_
}
if ($hashRaw.Count -eq 0) {
throw [System.Exception]::new("Cannot get $hashAlgo file hash from the file: $hashPath")
}
return $hashRaw[0]
}
}
process {
$splatGetHash = @{
ErrorAction = [System.Management.Automation.ActionPreference]::Stop
Algorithm = $Algorithm
}
[psvariable]$mainArg = Get-Variable -Name $PSCmdlet.ParameterSetName
if ([string]::IsNullOrEmpty($Hash)) {
# If the file path is specified, try to get hash from the text file
if ($mainArg.Name.EndsWith('Path', [System.StringComparison]::OrdinalIgnoreCase)) {
$Hash = $sbReadHash.Invoke($mainArg.Value, $Algorithm)
}
}
$splatGetHash.Add($mainArg.Name, $mainArg.Value)
try {
$hashObject = Get-FileHash @splatGetHash
}
catch {
$hashObject = $null
throw $_
}
[string]$hashCurrent = $hashObject.'Hash'
if ([string]::IsNullOrEmpty($hashCurrent)) {
throw [System.Exception]::new("The $Algorithm hash of the file $Path is empty")
}
return [string]::Equals($hashCurrent, $Hash, [System.StringComparison]::OrdinalIgnoreCase)
}
end {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment