Get-FileHash vs fc.exe for multi-TB restore verification: throughput vs early-exit trade-off
0 reputation · 26 Feb 2021, 05:01 UTC
0 reputation · 26 Feb 2021, 05:01 UTC
After restoring a 12 TB Windows Server Backup (wbadmin) snapshot to a new volume, the team needs an automated post-restore integrity check that fits within a four-hour maintenance window. Two documented approaches exist: Get-FileHash -Algorithm SHA256 (managed .NET streaming, single-threaded on PowerShell 5.1, parallelizable via ForEach-Object -Parallel on PowerShell 7+) and fc.exe (native binary compare, multi-threaded on recent Windows builds, exits on first mismatch but loads both files into memory).
The restore target includes 400,000 files ranging from 1 MB to 8 GB, with several hundred files exceeding 2 GB and a handful of alternate data streams (Zone.Identifier) that must be verified. Compare-Object is ruled out because it loads entire files into memory and corrupts the pipeline on binary null bytes. Robocopy /mir re-checks only size and timestamp, missing silent bit-flip corruption. No native cmdlet produces a reusable hash manifest for cross-session validation.
fc.exe’s early-exit on mismatch and multi-threaded comparison outweigh its memory pressure and lack of progress reporting when run at scale?Get-FileHash -Parallel (PowerShell 7.4) is used, what chunking strategy (per-directory vs fixed file-count batches) keeps CPU saturated without exhausting the runspace pool on an 8-core host?Get-FileHash per file, or a separate fc.exe pass on each named stream?35275 reputation · 26 Feb 2021, 09:30 UTC
For a 12 TB restore with 400,000 files, Get-FileHash -Algorithm SHA256 in PowerShell 7.4 is the superior choice because it generates a reusable manifest and supports Alternate Data Streams (ADS). While fc.exe offers an early-exit on mismatch, this only provides a speed advantage if the restore is already corrupted; for a successful restore, both tools must read the entire 12 TB. fc.exe also requires the source volume to be mounted and unchanged, creating a dependency that manifests avoid.
Likely Performance Dynamics:
Get-FileHash streams data, meaning 8 GB files will not cause Out-of-Memory (OOM) errors. fc.exe also streams binary comparisons rather than loading entire files into RAM, though it lacks the progress reporting and auditability of a hash list.Confirmed Technical Facts:
ForEach-Object -Parallel is exclusive to PowerShell 7+; PowerShell 5.1 is single-threaded for this operation.Get-FileHash -Stream allows direct hashing of Zone.Identifier without a separate file system pass.Compare-Object is safe for comparing CSV manifests (strings) even if the original files contained binary nulls.$PSVersionTable.PSVersion is 7.4+.ForEach-Object -Parallel -ThrottleLimit 8. This prevents runspace pool exhaustion that can occur with unpredictable per-directory grouping.Get-Item -Stream * to identify the Zone.Identifier stream and hash it using Get-FileHash -Stream.Compare-Object on the Hash and Path properties of the imported CSVs.Is the original source volume still accessible and frozen (read-only)? If the source is unavailable or has changed since the backup, fc.exe is technically impossible to use, making the manifest approach the only viable option.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.