# Get-FileHash.ps1
# Written by Bill Stewart (bstewart@iname.com)
#requires -version 2
<#
.SYNOPSIS
Outputs the MD5 or SHA1 hash for one or more files.
.DESCRIPTION
Outputs the MD5 or SHA1 hash for one or more files.
.PARAMETER Path
Specifies the path to one or more files. Wildcards are permitted.
.PARAMETER LiteralPath
Specifies a path to the file. Unlike Path, the value of LiteralPath is used exactly as it is typed. No characters are interpreted as wildcards. If the path includes escape characters, enclose it in single quotation marks.
.PARAMETER HashType
The hash type to compute; either MD5 or SHA1. The default is MD5.
.INPUTS
System.String, System.IO.FileInfo
.OUTPUTS
PSObjects containing the file paths and hash values
.EXAMPLE
PS C:\> Get-FileHash C:\Windows\Notepad.exe
Outputs the MD5 hash for the specified file.
.EXAMPLE
PS C:\> Get-FileHash C:\Windows\Explorer.exe,C:\Windows\Notepad.exe -HashType SHA1
Outputs the SHA1 hash for the specified files.
.EXAMPLE
PS C:\> Get-ChildItem C:\Scripts\*.ps1 | Get-FileHash
Outputs the MD5 hash for the specified files.
.EXAMPLE
PS C:\> Get-FileHash Download1.exe,Download2.exe -HashType SHA1
Outputs the SHA1 hash for two files. You can compare the hash values to determine if the files are identical.
#>
[CmdletBinding(DefaultParameterSetName="Path")]
param(
[Parameter(ParameterSetName="Path",Position=0,Mandatory=$TRUE,ValueFromPipeline=$TRUE)]
[String[]] $Path,
[Parameter(ParameterSetName="LiteralPath",Position=0,Mandatory=$TRUE)]
[String[]] $LiteralPath,
[Parameter(Position=1)]
[String] $HashType="MD5"
)
begin {
switch ($HashType) {
"MD5" {
$Provider = new-object System.Security.Cryptography.MD5CryptoServiceProvider
break
}
"SHA1" {
$Provider = new-object System.Security.Cryptography.SHA1CryptoServiceProvider
break
}
default {
throw "HashType must be one of the following: MD5 SHA1"
}
}
# If the Path parameter is not bound, assume input comes from the pipeline.
if ($PSCMDLET.ParameterSetName -eq "Path") {
$PIPELINEINPUT = -not $PSBOUNDPARAMETERS.ContainsKey("Path")
}
# Returns an object containing the file's path and its hash as a hexadecimal string.
# The Provider object must have a ComputeHash method that returns an array of bytes.
function get-filehash2($file) {
if ($file -isnot [System.IO.FileInfo]) {
write-error "'$($file)' is not a file."
return
}
$hashstring = new-object System.Text.StringBuilder
$stream = $file.OpenRead()
if ($stream) {
foreach ($byte in $Provider.ComputeHash($stream)) {
[Void] $hashstring.Append($byte.ToString("X2"))
}
$stream.Close()
}
"" | select-object @{Name="Path"; Expression={$file.FullName}},
@{Name="$($Provider.GetType().BaseType.Name) Hash"; Expression={$hashstring.ToString()}}
}
}
process {
if ($PSCMDLET.ParameterSetName -eq "Path") {
if ($PIPELINEINPUT) {
get-filehash2 $_
}
else {
get-item $Path -force | foreach-object {
get-filehash2 $_
}
}
}
else {
$file = get-item -literalpath $LiteralPath
if ($file) {
get-filehash2 $file
}
}
}