PowerShell By Example: Cryptographic Hashing

Hashing is the process of converting data into a fixed-length string using a mathematical algorithm. The same input always produces the same output, but the output cannot be reversed to recover the original input. Hashes are commonly used to verify file integrity, store passwords securely, and detect data changes.

PowerShell provides built-in support for hashing through Get-FileHash and the .NET [System.Security.Cryptography] namespace.


Get-FileHash

Get-FileHash computes the hash of a file. By default it uses SHA256.

Get-FileHash -Path "C:\Temp\example.txt"

Result:

Algorithm       Hash                                                             Path
---------       ----                                                             ----
SHA256          3B4C5D6E7F8A9B0C1D2E3F4A5B6C7D8E9F0A1B2C3D4E5F6A7B8C9D0E1F2A3B4  C:\Temp\example.txt

Choosing an Algorithm

The -Algorithm parameter lets you select from: MD5, SHA1, SHA256, SHA384, or SHA512.

Get-FileHash -Path "C:\Temp\example.txt" -Algorithm MD5
Get-FileHash -Path "C:\Temp\example.txt" -Algorithm SHA1
Get-FileHash -Path "C:\Temp\example.txt" -Algorithm SHA512

Result:

Algorithm       Hash                                 Path
---------       ----                                 ----
MD5             D41D8CD98F00B204E9800998ECF8427E     C:\Temp\example.txt
SHA1            DA39A3EE5E6B4B0D3255BFEF95601890AFD  C:\Temp\example.txt
SHA512          CF83E1357EEFB8BDF1542850D66D8007D6...  C:\Temp\example.txt

Note: MD5 and SHA1 are considered cryptographically weak and should not be used for security purposes. Prefer SHA256 or higher.


Hashing a String

Get-FileHash works on files, but you can hash a string by converting it to a stream first.

function Get-StringHash {
    param(
        [string]$Value,
        [string]$Algorithm = "SHA256"
    )

    $stream = [System.IO.MemoryStream]::new(
        [System.Text.Encoding]::UTF8.GetBytes($Value)
    )
    (Get-FileHash -InputStream $stream -Algorithm $Algorithm).Hash
}

Get-StringHash -Value "Hello, World!"
Get-StringHash -Value "Hello, World!" -Algorithm MD5

Result:

DFFD6021BB2BD5B0AF676290809EC3A53191DD81C7F70A4B28688A362182986F
65A8E27D8879283831B664BD8B7F0AD4

Verifying File Integrity

A common use case is verifying a downloaded file matches its published checksum.

$expectedHash = "3B4C5D6E7F8A9B0C1D2E3F4A5B6C7D8E9F0A1B2C3D4E5F6A7B8C9D0E1F2A3B4"
$actualHash   = (Get-FileHash -Path "C:\Temp\example.txt").Hash

if ($actualHash -eq $expectedHash) {
    Write-Host "File is valid. Hash matches."
} else {
    Write-Host "WARNING: Hash mismatch! File may be corrupted or tampered with."
    Write-Host "Expected: $expectedHash"
    Write-Host "Actual:   $actualHash"
}

Result (on a matching file):

File is valid. Hash matches.

Note that the -eq comparison is case-insensitive, so you don’t need to normalise the case of the hash string. See Case Sensitivity for more on this.


Hashing Multiple Files

You can pipe a list of files to Get-FileHash to hash them all at once.

Get-ChildItem -Path "C:\Temp" -File | Get-FileHash -Algorithm SHA256

Result:

Algorithm       Hash                                                             Path
---------       ----                                                             ----
SHA256          A1B2C3D4E5F6A7B8C9D0E1F2A3B4C5D6E7F8A9B0C1D2E3F4A5B6C7D8E9F0  C:\Temp\file1.txt
SHA256          B2C3D4E5F6A7B8C9D0E1F2A3B4C5D6E7F8A9B0C1D2E3F4A5B6C7D8E9F0A1  C:\Temp\file2.txt
SHA256          C3D4E5F6A7B8C9D0E1F2A3B4C5D6E7F8A9B0C1D2E3F4A5B6C7D8E9F0A1B2  C:\Temp\file3.txt

Comparing Two Files

You can use hashes to quickly check whether two files are identical without comparing them byte by byte.

$hash1 = (Get-FileHash -Path "C:\Temp\original.txt").Hash
$hash2 = (Get-FileHash -Path "C:\Temp\copy.txt").Hash

if ($hash1 -eq $hash2) {
    Write-Host "Files are identical."
} else {
    Write-Host "Files are different."
}

Result:

Files are identical.

Using .NET Directly

For more control, or for hashing data that is not a file, you can use .NET’s System.Security.Cryptography namespace.

$data      = [System.Text.Encoding]::UTF8.GetBytes("Hello, World!")
$sha256    = [System.Security.Cryptography.SHA256]::Create()
$hashBytes = $sha256.ComputeHash($data)

# Convert byte array to hex string
$hashHex = [System.BitConverter]::ToString($hashBytes) -replace "-", ""
$hashHex

Result:

DFFD6021BB2BD5B0AF676290809EC3A53191DD81C7F70A4B28688A362182986F

Summary

MethodUse case
Get-FileHashHash files on disk, simple and built-in
Get-FileHash -InputStreamHash strings or in-memory data
[System.Security.Cryptography]Fine-grained control, any data type

Prefer SHA256 or higher for any security-sensitive purpose. Use MD5 only when interoperability with legacy systems requires it.