/commands/powershell/get-filehash-sha256-md5
Get-FileHash: get the SHA256 or MD5 hash of a file in PowerShell
- tool
- PowerShell
- versions
- Windows PowerShell 5.1, PowerShell 7.x
- os
- windows, linux, macos
Get-FileHash FILE prints the SHA256 hash of a file in PowerShell; add -Algorithm MD5 (or SHA1, SHA384, SHA512) for another algorithm. It is the built-in way on Windows to check a download against the checksum its publisher lists, with no extra tools.
Get-FileHash .\setup.exe
Get-FileHash .\setup.exe -Algorithm MD5
(Get-FileHash .\setup.exe).Hash -eq 'PUBLISHED-HASH'Replace .\setup.exe with your file and PUBLISHED-HASH with the value from the vendor's page. The last line prints True or False.
Hash a file and compare it
The block writes a small file with fixed bytes, so the hashes are the same on every machine:
[IO.File]::WriteAllText("$PWD\hello.txt", "hello`n")
$h = Get-FileHash .\hello.txt
"$($h.Algorithm) $($h.Hash)"
(Get-FileHash .\hello.txt -Algorithm MD5).Hash
$h.Hash -eq '5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03'Output
SHA256 5891B5B522D5DF086D0FF0B110FBD9D21BB4FC7163AF34D08286A2E846F6BE03 B1946AC92492D2347C6235B4D2611184 True
The object has three properties: Algorithm, Hash (uppercase hexadecimal) and Path (the full path). -eq on strings is case-insensitive in PowerShell, so a lowercase checksum copied from a website compares correctly. Use -ceq only if you need a case-sensitive match.
Algorithms
Allowed values come from a ValidateSet on -Algorithm, so a typo fails before any file is read. In Windows PowerShell 5.1:
(Get-Command Get-FileHash).Parameters['Algorithm'].Attributes |
Where-Object { $_.ValidValues } | ForEach-Object { $_.ValidValues -join ', ' }
try { Get-FileHash $PSCommandPath -Algorithm SHA3 -ErrorAction Stop } catch { $_.Exception.Message }Output
SHA1, SHA256, SHA384, SHA512, MACTripleDES, MD5, RIPEMD160 Cannot validate argument on parameter 'Algorithm'. The argument "SHA3" does not belong to the set "SHA1,SHA256,SHA384,SHA512,MACTripleDES,MD5,RIPEMD160" specified by the ValidateSet attribute. Supply an argument that is in the set and then try the command again.
| Value | Use it for |
|---|---|
| SHA256 (default) | Checking downloads; what most vendors publish |
| SHA512 / SHA384 | When the publisher lists these; same command with -Algorithm |
| SHA1 / MD5 | Matching legacy checksums only; not secure against deliberate tampering |
| MACTripleDES / RIPEMD160 | Windows PowerShell 5.1 only; removed from PowerShell 7 |
PowerShell 7 accepts SHA1, SHA256, SHA384, SHA512 and MD5. Scripts that use RIPEMD160 or MACTripleDES fail there with the same ValidateSet error.
Common variants
| Task | Command |
|---|---|
| Every file in a folder | Get-ChildItem C:\dist -File | Get-FileHash | Select-Object Hash, Path |
| Recursive, to CSV | Get-ChildItem -Recurse -File | Get-FileHash | Export-Csv hashes.csv -NoTypeInformation |
| Path with [ ] characters | Get-FileHash -LiteralPath "report[1].pdf" |
| Hash of a string or stream | Get-FileHash -InputStream $stream |
| cmd.exe, no PowerShell | certutil -hashfile setup.exe SHA256 |
-Path treats [ and ] as wildcards, so a file named report[1].pdf is not found; -LiteralPath takes the name as typed.
Hash a string
$bytes = [Text.Encoding]::UTF8.GetBytes("hello`n")
$stream = [IO.MemoryStream]::new($bytes)
(Get-FileHash -InputStream $stream -Algorithm SHA256).HashOutput
5891B5B522D5DF086D0FF0B110FBD9D21BB4FC7163AF34D08286A2E846F6BE03
It matches the file hash above because the bytes are identical.
The same check in cmd
certutil -hashfile ships with Windows and prints lowercase hex. echo in cmd ends the line with CR LF, so this file has different bytes, and a different hash, than the one above:
>hello.txt echo hello
certutil -hashfile hello.txt SHA256Output
SHA256 hash of hello.txt: cd2eca3535741f27a8ae40c31b0c41d4057a7a7b912b33b9aed86485d1c84676 CertUtil: -hashfile command completed successfully.
Errors
A missing file is a non-terminating error: Get-FileHash writes Cannot find path '...' because it does not exist. and the script carries on with no hash. Add -ErrorAction Stop inside try/catch when the check must stop the script; see Cannot find path because it does not exist. Files locked by another process can also fail to open; close the program that holds them.
FAQ
What algorithm does Get-FileHash use by default?
SHA256, in both Windows PowerShell 5.1 and PowerShell 7. Pass -Algorithm SHA1, SHA384, SHA512 or MD5 for another one; the value is not case-sensitive.
Why does my hash not match the one on the download page?
Get-FileHash prints uppercase hex while most sites publish lowercase, but PowerShell's -eq comparison ignores case, so that is not the reason. A real mismatch means a different algorithm, a different file (for example an HTML error page saved under the installer's name) or an incomplete download.
Can Get-FileHash hash a string instead of a file?
Not directly. Wrap the bytes in a System.IO.MemoryStream and pass it to -InputStream, as the block on this page does. Choose the encoding explicitly, because the hash is computed over bytes, not characters.
Sources
- learn.microsoft.comlearn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-filehash?view=powershell-5.1
- learn.microsoft.comlearn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-filehash?view=powershell-7.5
- learn.microsoft.comlearn.microsoft.com/en-us/windows-server/administration/windows-commands/certutil