PowerShell Hash File: Verify File Integrity with Get-FileHash

PowerShell Hash File: Verify File Integrity with Get-FileHash

PowerShell Tips Editor 4 min read
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-256 throws “Cannot validate argument on parameter ‘Algorithm’.” The valid values are SHA1, SHA256, SHA384, SHA512, MD5, and MACTripleDES — no hyphens.
  • Case difference in hash comparison — normalize with .ToUpper(). Vendor-published hashes are sometimes lowercase. Get-FileHash always 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.

Send-Item -To