Skip to main content

How to Verify Multiple File Checksums in Batch Script

Generating a checksum manifest is only the first half of the security process; the real value comes during the Verification. When you restore a backup or download a multi-part installer, you need to compare every file against its original "Master" hash recorded in your manifest file. Manually checking a hundred hashes is impossible. A Batch script can "Parse" your manifest, re-calculate the fresh hash for each file on the disk, and alert you instantly if even one single bit has changed.

This guide will explain how to automate bulk checksum verification.

Method: The "Manifest Parser" Script

This script reads a text file formatted as FileName : Hash (the format created in our previous guide) and checks each file for integrity.

Implementation Script

@echo off
setlocal enabledelayedexpansion

set "Manifest=C:\Audit\manifest_md5.txt"
set "SearchDir=C:\MyArchive"
set "PassCount=0"
set "FailCount=0"

:: Verify inputs exist
if not exist "%Manifest%" (
echo [ERROR] Manifest file not found: %Manifest%
pause
exit /b 1
)
if not exist "%SearchDir%" (
echo [ERROR] Search directory not found: %SearchDir%
pause
exit /b 1
)

echo [AUDIT] Starting Bulk Verification...
echo Comparing files in %SearchDir% against %Manifest%
echo --------------------------------------------------

:: Loop through each line in the manifest
:: Skip header lines that do not match the "filename : hash" format
for /f "usebackq tokens=1,* delims=:" %%i in ("%Manifest%") do (
set "fname=%%i"
set "known_hash=%%j"

:: Clean up spaces from both values
set "fname=!fname: =!"
set "known_hash=!known_hash: =!"

:: Skip empty lines or header lines without a hash value
if defined known_hash (
:: Check if the file exists on disk
if not exist "%SearchDir%\!fname!" (
echo [MISSING] !fname!
set /a FailCount+=1
) else (
:: Re-calculate the current hash
set "actual_hash="
for /f "skip=1 tokens=*" %%h in ('certutil -hashfile "%SearchDir%\!fname!" MD5 2^>nul') do (
if not defined actual_hash set "actual_hash=%%h"
)
set "actual_hash=!actual_hash: =!"

:: Compare (case-insensitive for hex values)
if /i "!actual_hash!"=="!known_hash!" (
echo [OK] !fname!
set /a PassCount+=1
) else (
echo [ALERT] !fname! INTEGRITY MISMATCH
echo Expected: !known_hash!
echo Actual: !actual_hash!
set /a FailCount+=1
)
)
)
)

echo --------------------------------------------------
echo Results: !PassCount! passed, !FailCount! failed
if !FailCount! gtr 0 (
echo [WARNING] One or more files failed integrity verification.
) else (
echo [OK] All files match the manifest.
)

pause
endlocal

Method 2: Fast "Quick-Scan" Summary

If you don't need to know which file failed, just whether the whole set has changed, you can generate a fresh manifest and compare it against your baseline.

@echo off
setlocal enabledelayedexpansion

set "SearchDir=C:\MyArchive"
set "Original=C:\Audit\manifest_md5.txt"
set "Current=C:\Audit\manifest_current.txt"

:: Verify inputs exist
if not exist "%Original%" (
echo [ERROR] Original manifest not found: %Original%
pause
exit /b 1
)
if not exist "%SearchDir%" (
echo [ERROR] Search directory not found: %SearchDir%
pause
exit /b 1
)

echo [SCAN] Generating fresh manifest for comparison...

:: Generate a new manifest in the same format as the original
if exist "%Current%" del "%Current%"
for %%f in ("%SearchDir%\*.*") do (
set "current_hash="
for /f "skip=1 tokens=*" %%a in ('certutil -hashfile "%%f" MD5') do (
if not defined current_hash set "current_hash=%%a"
)
set "current_hash=!current_hash: =!"
echo %%~nxf : !current_hash! >> "%Current%"
)

echo [COMPARE] Checking for changes since last audit...

fc "%Original%" "%Current%" >nul 2>&1

if %errorlevel% equ 0 (
echo [VALID] No changes detected in the directory.
) else (
echo [WARNING] Differences detected! Run the full verification for details.
)

pause
endlocal

Method 3: The "Installation Guard"

Use this to verify a software package before you let your Batch script install it.

@echo off
setlocal

set "Installer=C:\Downloads\setup.exe"
set "RefHash=d41d8cd98f00b204e9800998ecf8427e"

:: Verify the installer exists
if not exist "%Installer%" (
echo [ERROR] Installer not found: %Installer%
pause
exit /b 1
)

echo [VERIFY] Checking integrity of %Installer%...

set "actual_hash="
for /f "skip=1 tokens=*" %%a in ('certutil -hashfile "%Installer%" MD5') do (
if not defined actual_hash set "actual_hash=%%a"
)
set "actual_hash=%actual_hash: =%"

if /i "%actual_hash%"=="%RefHash%" (
echo [OK] Integrity confirmed. Starting setup...
) else (
echo [ERROR] Installer integrity check FAILED!
echo Expected: %RefHash%
echo Actual: %actual_hash%
echo.
echo The file may be corrupted or tampered with.
pause
exit /b 1
)

endlocal

How to Avoid Common Errors

Wrong Way: Hardcoding the path in the manifest

If your manifest says C:\Work\file.txt, but you move the files to D:\Restore\, the script will fail because the path doesn't exist.

Correct Way: Use only the Filenames in your manifest. In your verification script (Method 1), combine the filename from the manifest with the SearchDir variable of the current machine. This makes your manifest portable.

Problem: Formatting Mismatch

If your manifest uses FILENAME:HASH but your script looks for FILENAME : HASH (with a space), the parsing logic might break or include extra spaces.

Solution: Use the space-removal substitution set "fname=!fname: =!" to scrub away any leading or trailing spaces before doing the comparison.

Best Practices and Rules

1. Identify "Missing" Files

If the manifest lists image.jpg but it was deleted from the disk, certutil will throw an error. Your script should check if not exist "%SearchDir%\!fname!" and report the file as "MISSING."

2. Matching the Algorithm

You can't verify an MD5 hash using a SHA-256 calculation. Ensure your script's certutil command matches the algorithm used to create the manifest.

3. Log the Failures

On a server with 10,000 files, the scrollbar will move too fast to see errors. Redirect the output to a "Failed_Files.log" so you can review only the broken items.

Conclusions

Verifying multiple checksums via Batch script is the ultimate "Gatekeeper" for data reliability. By moving from simple "Blind trust" to automated cryptographic verification, you protect your infrastructure from silent corruption and malicious actors. This professional oversight ensures that your backups are valid, your updates are authentic, and your digital assets remain 100% verified across their entire lifecycle.