Skip to content

Software / Practical guide

Checking files with PowerShell: SHA-256 and the right bytes

A reproducible PowerShell exercise: create a test file, calculate SHA-256, compare line endings and interpret results correctly. With a PDF edition.

From command to reproducible observation

A command is useful in teaching when the expected observation is clear beforehand. This exercise develops part of my “PowerShell verstehen” notes: create a small known file, examine its hash, then change only the line ending. This connects the checksum to the bytes actually stored.

The examples target PowerShell 7. They need no administrator rights, downloaded scripts or execution-policy changes. They create a randomly named practice folder in the temporary directory. Its files remain available for inspection.

1. Create a precisely defined test file

We write exactly the three ASCII bytes for abc. This makes the starting file independent of an editor’s text defaults.

$demoRoot = Join-Path ([IO.Path]::GetTempPath()) (
    'hash-demo-' + [Guid]::NewGuid().ToString('N')
)
[IO.Directory]::CreateDirectory($demoRoot) | Out-Null
$demoFile = Join-Path $demoRoot 'abc.txt'
[IO.File]::WriteAllBytes($demoFile, [byte[]](0x61, 0x62, 0x63))

Get-Item -LiteralPath $demoFile |
    Select-Object Name, Length, FullName

The length must be three bytes. The folder name differs each time. -LiteralPath treats the filename literally; characters such as square brackets are not interpreted as search patterns.

2. Calculate and compare the hash

Get-FileHash returns the algorithm, hash and path, among other fields. It reads the file to do so. The example explicitly specifies the algorithm. Details are documented by Microsoft for Get-FileHash.

$actual = Get-FileHash -LiteralPath $demoFile -Algorithm SHA256
$expected = 'BA7816BF8F01CFEA414140DE5DAE2223' +
            'B00361A396177A9CB410FF61F20015AD'

$actual | Select-Object Algorithm, Hash, Path
$actual.Hash -eq $expected

The comparison must return True . The expected value matches the input defined in step 1. For a real download I would obtain it from a trusted source. A newly calculated value is not an independent reference for origin.

3. Add only a line ending

Now we create two more files. Their visible text is still abc, but their byte sequences differ.

$lfFile = Join-Path $demoRoot 'abc-lf.txt'
$crlfFile = Join-Path $demoRoot 'abc-crlf.txt'
[IO.File]::WriteAllBytes($lfFile, [byte[]](0x61, 0x62, 0x63, 0x0A))
[IO.File]::WriteAllBytes(
    $crlfFile, [byte[]](0x61, 0x62, 0x63, 0x0D, 0x0A)
)

Get-ChildItem -LiteralPath $demoRoot -File |
    Get-FileHash -Algorithm SHA256 |
    Select-Object Hash, Path

There must be three different hash values. The files contain three, four and five bytes. LF adds one byte; CRLF adds two. A different hash alone does not mean the human-readable content has changed substantially.

Encoding also matters for your own text files. Windows PowerShell and newer versions have different defaults for several text commands. Explicit bytes avoid these differences here. In a text workflow, choose encoding and line endings deliberately. Microsoft: character encoding

4. Treat the result as an object

$actual.Hash accesses a property of the result object. The visible table represents that object. You do not need to split a screen line by spaces to compare the value. For this task, that is a practical advantage of the PowerShell pipeline.

$actual | Get-Member
$actual.Hash.Length

The hexadecimal value must have length 64. I would format for display only at the end. After formatting commands, you no longer work with the same domain properties as in the original result object.

How I would investigate differences

First I would check the full path: was the expected file actually read? Then file size, line endings, encoding and possibly another export. A file can also change between checks, so record the time and version.

This exercise uses known test files. It neither searches working directories nor modifies existing files. In class, write down the expected length or property before each step and compare afterwards. An incorrect expectation helps reveal an unclear assumption.

Verification of this edition

The four code blocks were run together on 18 September 2026 using PowerShell 7.6.6 on an Apple Silicon Mac. The hash comparison for abc returned True; the files contained three, four and five bytes, with three different SHA-256 values. The hexadecimal value had 64 characters. This documents that particular run; other operating systems were not separately tested for this edition.

What can we conclude?

We obtained the expected hash for a defined byte sequence and observed that additional line-ending bytes produce other values. This is a concrete, repeatable observation. It does not test for malware, authorship or substantive correctness.

The background is explained in Understanding SHA-256. Confidentiality and origin lead to the next question about encryption and digital signatures.

Reading edition / Version 1.0

Read and keep as PDF

An exercise on SHA-256, line endings and result objects. The compact edition contains the article, examples and sources. Interactive features remain in the web version.

Download PDF · 3 pages · 78 KB DE

Raphael Lugmayr · 18 September 2026 · Version 1.0. For recommendations and citations, link to this article page, which also includes revisions and supplementary materials.

Checksum of this PDF edition

SHA-256 compares downloaded bytes with this edition. A hash on the same website is not independent confirmation of origin.

14807330d07c918570ecdd8fdd815f74f1cf443fea3caf706aba96aea10ed596

All guides & materials

Sources & further reading

  1. Microsoft: Get-FileHash
  2. Microsoft: character encoding in PowerShell
  3. Microsoft: object pipelines in PowerShell

Related projects

belegwerk

Read next

  1. Software / Practical guide / 5 min.

    Understanding SHA-256: from bytes to a hash

    Why a SHA-256 hash has 64 hexadecimal characters, how bytes matter and what a checksum actually establishes. With examples, a browser demo and PDF.

Quick access / The archive

Start here