Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- NOTES:
- 11 JANUARY 2022
- BELOW IS A WINDOWS BATCH FILE THAT MAKES USE OF HASHDEEP FOR GENERATING AND VALIDATING MD5 HASHES OF FILES IN SPECIFIED FOLDER (INCLUDING ALL SUBFOLDERS).
- HASHDEEP IS OPEN SOURCE AND FREELY DISTRIBUATABLY, DOWNLOAD FROM GITHUB (VERSION 4.4): https://github.com/jessek/hashdeep/
- YOU WILL ONLY NEED THE FILE 'HASHDEEP64.EXE' WHICH SHOULD BE PLACED IN THE SAME FOLDER AS THE BELOW BATCH FILE.
- WHEN GENERATING HASHES, THE HASH FILE WILL BE STORED IN THE SAME FOLDER THE BATCH FILE IS PLACED AND WILL MAKE A "LOGS" SUB FOLDER WHERE ALL LOG FILES WILL BE STORED WITH THE FILE NAME MASK "[FOLDERNAME]_[DATESTAMP]_FULLHASHLIST.TXT". DATESTAMP WILL USE YYYYMMDD FORMAT. FILENAME CAN BE CHANGED TO WHATEVER YOU WISH AFTER CHECKSUMS ARE GENERATED. (I.E. BACKUPS_20220110_FULLHASHLIST.TXT)
- WHEN YOU PERFORM A COMPARISON OF A PREVIOUS HASH LIST TO ANOTHER FOLDER, THE FILE MUST BE PLACED IN THE SAME FOLDER THE BATCH FILE EXISTS, UNDER THE LOGS SUBFOLDER, AND TYPE FULL NAME OF FILE WITH EXTENSION (I.E. .TXT). AFTER HASHES ARE COMPARED IT WILL GENERATE A FILE IN THE LOGS SUBFOLDER WITH THE FILE NAME MASK "[FOLDERNAME]_[DATESTAMP]_FULLHASHSUMMARY.TXT" (I.E. BACKUPS_20220110_FULLHASHSUMMAR.TXT)
- IF NO ISSUES ARE FOUND THE REPORT WILL SAY "PASSED: NO ISSUES FOUND"
- IF THERE ARE DISCREPENCIES IT WILL SHOW FOUR CATGORIES:
- 1. FILENAMES WITH HASHES BUT DIFFERENT FILENAME (LIKELY MOVED/RENAMED)
- 2. FILES WITH SAME FILENAME BUT DIFFERENT HASH (LIKELY MODIFIED OR CORRUPT)
- 3. FILENAMES IN CHECKED DIRECTORY WITH NO MATCHING HASH (LIKELY NEW *OR* NAME CHANGED WITH CONTENTS MODIFIED OR CORRUPT)
- 4. FILENAMES WITH HASH THAT DO NOT EXIST IN CHECKED DIRECTORY (LIKELY DELETED OR MOVED OUTSIDE OF CHECKED DIRECTORY)
- IF THERE ARE NO FILES LISTED THEN THERE WERE NO ISSUES WITH THAT PARTICULAR CATEGORY.
- THE PROGRAM WILL SCAN THE FOLDER ENTERED BY THE USER FOR TOTAL FILE SIZE, TOTAL NUMBER OF FILES, AND TOTAL NUMBER OF FOLDERS WITH A TIME ESTIMATE TO COMPLETE ASSUMING 100MB/SEC. THIS IS NOT NECESSARY AND CAN TAKE A LITTLE WHILE IF YOU HAVE A LOT OF FILES, BUT INCLUDED IT BECAUSE PERSONALLY I LIKE TO HAVE THIS INFORMATION. YOU CAN REMOVE THIS FUNCTION IF DESIRED BY REMARKING OUT THE LINE (THERE ARE TWO, ONE FOR INITIAL CHECKSUM, SECOND FOR VALIDATION):
- CALL :foldersize
- BELOW IS THE BATCH FILE. COPY/PASTE EVERYTHING BELOW THE ####### MARKS INTO A NOTEPAD DOCUMENT AND SAVE AS "HASHDEEPBATCH.BAT". YOU CAN NAME IT WHATEVER YOU WANT THOUGH. JUST BE SURE HASHDEEP64.EXE EXISTS IN SAME FOLDER WHEREVER YOU PUT BATCH FILE.
- ####################################################
- @ECHO OFF
- :START
- cls
- REM Set current folder to batch folder
- CALL :CLEARSET
- set "batchdir=%~dp0"
- cd /d "%batchdir%"
- IF NOT EXIST "LOGS\" MD "LOGS\"
- if not exist "%batchdir%hashdeep64.exe" ECHO Make sure the file "hashdeep64" are in your system path or same folder as this batch file & ECHO,
- ECHO ****************************************************************************************
- ECHO * HASHDEEPBATCH by HTWINGNUT 10 JAN 2022 *
- ECHO * - HASHDEEP MD5 Checksum Hash and Validation of Files *
- ECHO * *
- ECHO * !!! USE AT YOUR OWN RISK. I TAKE NO RESPONSIBILITY ANY ERRORS OR ISSUES !!! *
- ECHO * *
- ECHO * THIS BATCH FILE REQUIRES: *
- ECHO * - HASHDEEP64.EXE from http://md5deep.sourceforge.net/ or *
- ECHO * https://github.com/jessek/hashdeep *
- ECHO * *
- ECHO ****************************************************************************************
- ECHO,
- REM SET DAY TIME STAMP STORED IN %logtime% VARIABLE
- REM Determine if hour is one or two digits
- set hournum=%time:~0,2%
- set logdate=%date:~10,4%%date:~4,2%%date:~7,2%
- REM Set up filename depending on time is one or two digits
- if %hournum% gtr 9 (set logtime=%date:~10,4%%date:~4,2%%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%) else (set logtime=%date:~10,4%%date:~4,2%%date:~7,2%_0%time:~1,1%%time:~3,2%%time:~6,2%)
- ECHO,
- ECHO Do you want to:
- ECHO [H]ash all the files in a specified folder
- ECHO [C]ompare hashes of a folder with a previously hashed set of files
- ECHO e[X]it
- ECHO,
- CHOICE /C HCX /N /M "[H]ash, [C]ompare, or e[X]it > "
- IF %ERRORLEVEL% EQU 1 GOTO :hashit
- IF %ERRORLEVEL% EQU 2 GOTO :HASHCHECK
- IF %ERRORLEVEL% EQU 3 GOTO :DONE
- REM *************************************************************
- REM Independent Hash Routine Using HASHDEEP
- :HASHIT
- CLS
- :HASHNEW
- set "sourcedir="
- ECHO,
- ECHO Entering path and pressing [ ENTER ] will immediately start hash calcuations.
- ECHO,
- set /p "sourcedir=Full Path of Directory to Hash (x to exit) > "
- IF /I "%sourcedir%" == "x" GOTO :START
- IF NOT ["%sourcedir%"]==[""] GOTO :checkh1
- ECHO,
- ECHO *** No Path Entered
- ECHO *** Please enter full directory path (i.e. C:\ D:\archive etc)
- ECHO,
- GOTO :HASHNEW
- :checkh1
- if exist "%sourcedir%\" goto :HASHSTART
- ECHO,
- ECHO *** No such path exists.
- ECHO *** Please enter full directory path (i.e. C:\ D:\archive etc)
- ECHO,
- GOTO :HASHNEW
- :HASHSTART
- CLS
- CALL :HASHSUB
- PAUSE
- GOTO :START
- REM *************************************************************
- :HASHCHECK
- CLS
- :hashcheck2
- ECHO,
- set /p sourcedir="Full Path of Directory to Check Hash (x to exit) > "
- IF ["%sourcedir%"] EQU ["x"] GOTO :START
- IF NOT ["%sourcedir%"]==[""] GOTO :hashcheck3
- ECHO,
- ECHO *** No Path Entered
- ECHO *** Please enter full directory path (i.e. C:\ D:\archive etc)
- ECHO,
- GOTO :hashcheck2
- :hashcheck3
- if exist "%sourcedir%\" goto :hashcheck4
- ECHO,
- ECHO *** No such path exists.
- ECHO *** Please enter full directory path (i.e. C:\ D:\archive etc)
- ECHO,
- GOTO :hashcheck2
- :hashcheck4
- CALL :hashfilecheck
- REM !!! REMARK OUT OR DELETE BELOW CALL LINE IF YOU DO NOT WANT FOR FILE STATS TO RUN
- CALL :foldersize
- ECHO,
- PAUSE
- :HASHCHECKSTART
- CALL :SDIRLEN
- CD /D "%batchdir%"
- ECHO,
- ECHO REFERENCING FILE: "%hashfilen%"
- ECHO VERIFY HASH OF FILES IN: "%sourcedir%"
- ECHO,
- ECHO,
- ECHO Validating Checksums...
- ECHO,
- REM *************************************************************
- REM START HASHCHECK
- pushd "%sourcedir%"
- "%batchdir%hashdeep64.exe" -k "%batchdir%LOGS\%hashfilen%" -avv -of -elr * > "%batchdir%hashauditraw.txt"
- popd
- REM This was used when _ZIPHASHBURN_ folder was in same folder as data, not needed anymore.
- REM findstr /V C:"_ZIPHASHBURN_" "hashauditraw_.txt" > hashauditraw.txt
- REM del /q /f "hashauditraw_.txt"
- del __hash*.txt 2>NUL
- REM.>__hashnomatch.txt
- REM.>__hashnomatchfiles.txt
- REM.>__hashnotused.txt
- REM.>__hashnotusedfiles.txt
- SET "hashsummary=%batchdir%LOGS\%folderzip%_%logtime%_FULLHASHSUMMARY.TXT"
- ECHO *** %date% %time% >> %hashsummary%
- ECHO *** USING HASH FILE: "%hashfilen%" >> %hashsummary%
- ECHO *** CHECKING FOLDER: "%sourcedir%" >> %hashsummary%
- ECHO, >> %hashsummary%
- SET "PASSED="
- FOR /F "tokens=*" %%a in ('FINDSTR /C:".exe\: Audit Passed" /L /I "hashauditraw.txt"') DO ( SET "PASSED=%%a" )
- IF DEFINED PASSED (
- ECHO *** PASSED: NO ISSUES FOUND
- ECHO *** PASSED: NO ISSUES FOUND >> %hashsummary%
- GOTO :HCHECKDONE
- )
- ECHO *** FILENAMES WITH MATCHING HASHES BUT DIFFERENT FILENAMES (LIKELY MOVED/RENAMED) >> %hashsummary%
- FINDSTR /C:": Moved from" /I hashauditraw.txt >> %hashsummary%
- ECHO, >> %hashsummary%
- ECHO, >> %hashsummary%
- ECHO *** FILES WITH SAME FILENAME BUT DIFFERENT HASH (LIKELY MODIFIED OR CORRUPT) >> %hashsummary%
- FINDSTR /C:": No match" /I hashauditraw.txt > __hashnomatch.txt
- FOR /F "usebackq tokens=1* delims=:" %%Q in ("__hashnomatch.txt") DO (echo %%Q) >> __hashnomatchfiles.txt
- FINDSTR /C:": Known file not used" /I hashauditraw.txt > __hashnotused.txt
- FOR /F "usebackq tokens=1* delims=:" %%R in ("__hashnotused.txt") DO (echo %%R) >> __hashnotusedfiles.txt
- FOR /F "usebackq delims=" %%S in ("__hashnotusedfiles.txt") DO (
- FOR /F "usebackq delims=" %%T in ("__hashnomatchfiles.txt") DO (
- IF ["%%S"] EQU ["%%T"] ECHO %%S >> %hashsummary%
- )
- )
- ECHO, >> %hashsummary%
- ECHO, >> %hashsummary%
- ECHO *** FILENAMES IN CHECKED DIRECTORY WITH NO MATCHING HASH (LIKELY NEW *OR* NAME CHANGED WITH CONTENTS MODIFIED OR CORRUPT) >> %hashsummary%
- SET FOUND=0
- FOR /F "usebackq delims=" %%U in ("__hashnomatchfiles.txt") DO (
- SETLOCAL ENABLEDELAYEDEXPANSION
- FOR /F "usebackq delims=" %%V in ("__hashnotusedfiles.txt") DO (
- IF ["%%U"] EQU ["%%V"] SET FOUND=1
- )
- IF !FOUND! EQU 1 (ECHO,) ELSE (
- SET FOUND=0
- ECHO %%U >> %hashsummary%
- )
- ENDLOCAL
- )
- ECHO, >> %hashsummary%
- ECHO, >> %hashsummary%
- ECHO *** FILENAMES WITH HASH THAT DO NOT EXIST IN CHECKED DIRECTORY (LIKELY DELETED OR MOVED OUTSIDE OF CHECKED DIRECTORY) >> %hashsummary%
- SET FOUND=0
- FOR /F "usebackq delims=" %%W in ("__hashnotusedfiles.txt") DO (
- SETLOCAL ENABLEDELAYEDEXPANSION
- FOR /F "usebackq delims=" %%X in ("__hashnomatchfiles.txt") DO (
- IF ["%%W"] EQU ["%%X"] SET FOUND=1
- )
- IF !FOUND! EQU 1 (ECHO,) ELSE (
- SET FOUND=0
- ECHO %%W >> %hashsummary%
- )
- ENDLOCAL
- )
- :HCHECKDONE
- del __hash*.txt 2>NUL
- ECHO,
- ECHO HASH CHECK COMPLETE!
- ECHO,
- ECHO Results are stored in "%hashsummary%"
- ECHO CONTENTS OF FILE BELOW:
- ECHO,
- TYPE "%hashsummary%"
- ECHO,
- ECHO,
- ECHO **************************************************************
- ECHO *** PRESSING [ ENTER ] WILL TAKE YOU BACK TO THE MAIN MENU ***
- ECHO **************************************************************
- ECHO,
- pause
- GOTO :START
- REM *************************************************************
- :HASHSUB
- CALL :SDIRLEN
- REM !!! REMARK OUT OR DELETE BELOW CALL LINE IF YOU DO NOT WANT FOR FILE STATS TO RUN
- CALL :FOLDERSIZE
- ECHO,
- PAUSE
- :HASHSUB_1
- ECHO,
- ECHO STARTING HASH OF ALL FILES AND FOLDERS UNDER "%sourcedir%"
- ECHO %DATE% %TIME%
- ECHO,
- ECHO,
- SET "HASHLOG=LOGS\%folderzip%%fileext%_%logtime%_FULLHASHLIST.txt"
- REM TYPE NUL>hashlisttemp.txt
- pushd %sourcedir%
- "%batchdir%hashdeep64.exe" -cmd5 -of -elr * > "%batchdir%%HASHLOG%"
- popd
- ECHO,
- ECHO HASH COMPLETE!
- ECHO %DATE% %TIME%
- ECHO,
- ECHO Hash values are stored in "%batchdir%%HASHLOG%"
- ECHO KEEP THIS FILE FOR FUTURE HASH VALIDATION
- ECHO,
- GOTO :EOF
- REM *************************************************************
- :hashfilecheck
- ECHO,
- ECHO The reference file should be in the same folder as this batch file under the LOGS folder:
- ECHO "%batchdir%LOGS\"
- ECHO,
- PUSHD "LOGS\"
- set /p hashfilen="Name of File Containing Hashes to Verify (x to exit) > "
- IF ["%hashfilen%"] EQU ["x"] (
- POPD
- GOTO :START
- )
- IF NOT ["%hashfilen%"]==[""] GOTO :hashcheck1
- ECHO,
- ECHO *** No Filename Entered
- ECHO *** Please verify and re-enter filename
- ECHO,
- GOTO :hashfilecheck
- :hashcheck1
- if exist "%hashfilen%" (
- if exist "%hashfilen%\" ( ECHO >NUL ) ELSE (
- POPD
- GOTO :EOF
- )
- )
- ECHO,
- ECHO *** No such file exists.
- ECHO *** Please re-enter proper filename located in same folder as this batch file
- ECHO,
- POPD
- GOTO :hashfilecheck
- REM DEBUG: broke through hashfilecheck subroutine
- pause
- REM ########
- :DONE
- ENDLOCAL
- EXIT
- REM ########
- :FOLDERSIZE
- set "tsize=0"
- set "tsizemb=0"
- set "tsizebyte=0"
- set "fsizemb=0"
- set "fsizebyte=0"
- set "size=0"
- set "folder=%sourcedir%"
- set "filecount=0"
- set "foldcount=0"
- set "fpath_="
- set "tsizegb=0"
- set "tsizemb_=0"
- set "speed=0"
- ECHO %date% %time% >fsize.log
- REM COUNT FILES
- REM for /r "%folder%" %%x in ("*") do (
- for /f "tokens=* delims=" %%x in ('dir /b /s /a:-d "%folder%\*"') do (
- set "fsize=%%~zx"
- set "file=%%~pnxx"
- set "fpath=%%~px"
- call :addfiles
- )
- ECHO,
- REM COUNT DIRECTORIES
- For /f %%d in ('dir /b /s /a:d "%folder%"^|find /c /v ""') do CALL :addfolders %%d
- CLS
- ECHO FINISHED SCANNING: "%folder%"
- ECHO,
- SET tsizemb_=%tsizemb:~-3%
- IF %tsizemb% GEQ 1000 SET tsizegb=%tsizemb:~0,-3%
- ECHO TOTAL SIZE: %tsizemb%%tsizebyte:~-6% bytes (%tsizegb%.%tsizemb_% GB)
- ECHO TOTAL FILES: %filecount%
- ECHO TOTAL FOLDERS: %foldcount%
- ECHO,
- SET /A SPEED=%tsizemb%/6000
- IF %SPEED% EQU 0 SET "SPEED=LESS THAN 1"
- ECHO APPROXIMATE TIME TO CHECKSUM ALL FILES (at 100 MB/sec): %SPEED% MINUTES
- GOTO :EOF
- :addfiles
- SET "fsizemb=0"
- IF ["%fpath_%"] NEQ ["%fpath%"] (
- CALL :SHOWPATH
- )
- IF %fsize% GEQ 1000000 SET "fsizemb=%fsize:~0,-6%"
- SET "fsizebyte=%fsize:~-6%"
- FOR /F "tokens=* delims=0" %%a in ("%fsizebyte%") DO SET fsizebyte=%%a
- IF [%fsizebyte%] EQU [] SET fsizebyte=0
- SET /A filecount+=1
- SET /A tsizemb+=%fsizemb%
- SET /A tsizebyte+=%fsizebyte%
- IF %tsizebyte% GEQ 1000000 CALL :RESETBYTE
- GOTO :EOF
- :addfolders
- SET foldcount=%1
- GOTO :EOF
- :RESETBYTE
- SET /A tsizemb+=%tsizebyte:~0,-6%
- SET tsizebyte=%tsizebyte:~-6%
- REM ECHO tsizebyte %tsizebyte%
- FOR /F "tokens=* delims=0" %%a in ("%tsizebyte%") DO SET tsizebyte=%%a
- IF [%tsizebyte%] EQU [] SET tsizebyte=0
- GOTO :EOF
- :SHOWPATH
- SET "fpath_=%fpath%"
- CLS
- ECHO SCANNING: %fpath_%
- GOTO :EOF
- REM ########
- :SDIRLEN
- SET "folderzip="
- SET "sd=%sourcedir:~0,1%"
- SET "pathtemp=%sourcedir:~-1%"
- IF ["%pathtemp%"] EQU ["\"] (set "sourcedir=%sourcedir%") ELSE (set "sourcedir=%sourcedir%\")
- FOR %%i in ("%sourcedir:~0,-1%") DO (SET "folderzip=%%~nxi")
- SET "folderzip=%folderzip: =_%"
- REM USE BELOW IF YOU WANT TO INCLUDE DRIVE LETTER
- REM SET "folderzip=%sd%_%folderzip%"
- CALL :STRLEN "%sourcedir%" _sdlen
- ECHO,
- GOTO :EOF
- REM ########
- :CLEARSET
- SET "_sdeln="
- SET "batchdir="
- SET "count="
- SET "fileext="
- SET "filepath="
- SET "folderzip="
- SET "FOUND="
- SET "hashfilen="
- SET "HASHLOG="
- SET "hashsummary="
- SET "hournum="
- SET "len="
- SET "logtime="
- SET "logdate="
- SET "PASSED="
- SET "password="
- SET "pathtemp="
- SET "sourcedir="
- set "tsizemb="
- set "tsizebyte="
- set "fsizemb="
- set "fsizebyte="
- set "size="
- set "filecount="
- set "foldcount="
- set "fpath_="
- set "tsizegb="
- set "tsizemb_="
- set "speed="
- GOTO :EOF
- REM ########
- :STRLEN
- Setlocal EnableDelayedExpansion
- :: strLen String [RtnVar]
- :: -- String The string to be measured, surround in quotes if it contains spaces.
- :: -- RtnVar An optional variable to be used to return the string length.
- Set "s=#%~1"
- Set "len=0"
- For %%N in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
- if "!s:~%%N,1!" neq "" (
- set /a "len+=%%N"
- set "s=!s:~%%N!"
- )
- )
- Endlocal&if "%~2" neq "" (set %~2=%len%) else echo %len%
- GOTO :EOF
Add Comment
Please, Sign In to add comment