PowerShell Hash File: Verify File Integrity with Get-FileHash

Downloading software installers or deployment packages without verifying their integrity is a security risk you can eliminate in seconds. The PowerShell get file hash cmdlet, Get-FileHash, computes cryptographic checksums for any file, letting you confirm the file matches a vendor-published hash before you run it. This post covers single-file verification, bulk auditing, and building a hash baseline for tamper detection.
Quick Answer / TL;DR
Run Get-FileHash -Path C:\file.exe -Algorithm SHA256 to get the SHA256 hash of a file. Compare the output .Hash property (uppercase string) against the vendor-published value.
Get-FileHash Basic Usage
Get-FileHash returns an object with three properties: Algorithm, Hash, and Path. The Hash property is always uppercase hexadecimal. By default, the algorithm is SHA256, which is the current industry standard for integrity verification. You can pipe files from Get-ChildItem directly into Get-FileHash.
# Hash a single file (default SHA256)
Get-FileHash -Path C:\Downloads\setup.exe
# Access just the hash string
(Get-FileHash -Path C:\Downloads\setup.exe).Hash
Algorithm Hash Path
--------- ---- ----
SHA256 3A7BD3E2360A3D29EEA436FCFB7E44719FE7BCF6E8D5A0BFED6A3B6E3C3D4F1 C:\Downloads\setup.exe
SHA256 vs MD5 vs SHA1
Choose the algorithm based on what the software vendor publishes. SHA256 is preferred — it is collision-resistant and widely supported. MD5 and SHA1 are legacy algorithms vulnerable to collision attacks; use them only when the vendor provides no SHA256 value. Pass the algorithm name exactly as shown: SHA256, MD5, SHA1, SHA384, or SHA512. Note: the parameter name is SHA256 not SHA-256.
# MD5 hash (legacy — use only when required)
Get-FileHash -Path C:\Downloads\patch.msp -Algorithm MD5
# SHA512 for maximum assurance
Get-FileHash -Path C:\Certs\root.cer -Algorithm SHA512
Compare Hash to Published Value
The safest comparison normalizes both strings to the same case before comparing. The .Hash property is already uppercase; call .ToUpper() on the published value to handle any case differences in vendor documentation.
$publishedHash = '3a7bd3e2360a3d29eea436fcfb7e44719fe7bcf6e8d5a0bfed6a3b6e3c3d4f1'
$fileHash = (Get-FileHash -Path C:\Downloads\setup.exe -Algorithm SHA256).Hash
if ($fileHash -eq $publishedHash.ToUpper()) {
Write-Host 'Hash verified. File is intact.' -ForegroundColor Green
} else {
Write-Warning 'Hash mismatch! File may be corrupted or tampered.'
}
Detect Changed Files
Store baseline hashes and compare them on a schedule to detect unauthorized modifications. This pattern is useful for monitoring configuration files, scripts, or binaries that should never change outside a deployment process.
$baseline = 'C:\Audit\baseline.csv'
# Build baseline
Get-ChildItem -Path C:\CriticalApp -Recurse -File |
Get-FileHash -Algorithm SHA256 |
Export-Csv -Path $baseline -NoTypeInformation
# Later: detect changes
$current = Get-ChildItem -Path C:\CriticalApp -Recurse -File |
Get-FileHash -Algorithm SHA256
$baselineData = Import-Csv $baseline
foreach ($file in $current) {
$orig = $baselineData | Where-Object Path -eq $file.Path
if ($orig -and $orig.Hash -ne $file.Hash) {
Write-Warning "CHANGED: $($file.Path)"
}
}
Hash All Files in a Folder
Pipe Get-ChildItem output directly into Get-FileHash. Use -Recurse to include subdirectories. This is an efficient one-liner for auditing an entire directory tree.
Get-ChildItem -Path C:\Deploy -Recurse -File |
Get-FileHash -Algorithm SHA256 |
Format-Table Algorithm, Hash, Path -AutoSize
Export Hashes as Baseline
Export hash results to CSV so they can be imported and compared later. The -NoTypeInformation switch keeps the CSV clean for consumption by other tools. Store the baseline in a location that is itself monitored or version-controlled.
Get-ChildItem -Path C:\WebRoot -Recurse -File |
Get-FileHash -Algorithm SHA256 |
Select-Object Algorithm, Hash, Path |
Export-Csv -Path C:\Audit\webroot_hashes_$(Get-Date -Format yyyyMMdd).csv -NoTypeInformation
Write-Host "Baseline saved to C:\Audit\"
Common Errors and Fixes
- Algorithm name must match exactly (SHA256 not SHA-256). Passing
-Algorithm SHA-256throws “Cannot validate argument on parameter ‘Algorithm’.” The valid values areSHA1,SHA256,SHA384,SHA512,MD5, andMACTripleDES— no hyphens. - Case difference in hash comparison — normalize with .ToUpper(). Vendor-published hashes are sometimes lowercase.
Get-FileHashalways returns uppercase. Use$publishedHash.ToUpper()before comparing to avoid false mismatches.
Related Cmdlets / See Also
Wrapping Up
Get-FileHash makes file integrity verification a one-liner. Use SHA256 by default, normalize case before comparing, and build baseline exports for ongoing tamper detection. For any downloaded binary, checking the hash before execution is a habit worth building into every deployment script.


