← Code

Make a file integrity manifest

List relative paths, file sizes, and SHA-256 hashes for a directory.

Tested locally with PowerShell 7 and fixture directories.

Get-FileManifest.ps1
<#
.SYNOPSIS
Creates a SHA-256 file inventory without changing the source directory.
.EXAMPLE
./Get-FileManifest.ps1 -Path ./deployment | ConvertTo-Json | Set-Content ./manifest.json
#>
[CmdletBinding()]
param(
[Parameter(Mandatory)][ValidateNotNullOrEmpty()][string]$Path
)
$ErrorActionPreference = 'Stop'
$manifestRoot = (Resolve-Path -LiteralPath $Path).ProviderPath
if (-not (Test-Path -LiteralPath $manifestRoot -PathType Container)) {
throw 'Path must point to a directory.'
}
Get-ChildItem -LiteralPath $manifestRoot -File -Recurse |
Where-Object { -not ($_.Attributes -band [IO.FileAttributes]::ReparsePoint) } |
Sort-Object FullName |
ForEach-Object {
[pscustomobject]@{
Path = [IO.Path]::GetRelativePath($manifestRoot, $_.FullName).Replace('\', '/')
Bytes = $_.Length
SHA256 = (Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256).Hash.ToLowerInvariant()
}
}

Create a manifest

Terminal window
$files = @(./Get-FileManifest.ps1 -Path ./deployment)
ConvertTo-Json -InputObject $files |
Set-Content ./manifest.json

The array wrapper keeps the JSON shape consistent for zero, one, or several files. Each entry has Path, Bytes, and SHA256. Paths are relative and use forward slashes.

Write the manifest outside the inventoried directory so it does not appear in the next inventory.

Compare builds

Generate manifests from immutable build directories. Compare entries by path and hash; timestamps are not part of the output.

The script omits hidden files by default and skips file reparse points. It does not capture permissions or empty directories. Files can change during hashing, so an actively changing directory can produce an inconsistent inventory.

Hashes identify byte changes. Keep the reference manifest in a protected location; this script does not sign it or authenticate its author.

Parameters

NameDefaultPurpose
PathRequiredDirectory to inventory recursively.

Requirements

Requires
  • PowerShell 7.
  • A readable directory.
Permissions
Read access to the selected directory and its files.
Testing
Checked with PowerShell 7 using directory fixtures, including a path with spaces.
Version
1.0.0