Guest User

Windows Differential Backup Script v1.4.6

a guest
Feb 8th, 2013
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Winbatch 30.04 KB | None | 0 0
  1. :: Purpose:         Rotating differential backup using 7-Zip for compression.
  2. :: Requirements:    - forfiles.exe from Microsoft
  3. ::                  - 7-Zip
  4. :: Author:          vocatus on reddit.com/r/usefulscripts
  5. :: Version:         1.4.6 + Added two additional "help" flags: "-h" and "--help"
  6. ::                  1.4.5 + Added better instructions for what variables can be set to
  7. ::                  1.4.4 + Added quotes around variables that could contain spaces in a few places
  8. ::                        * Some comment cleanup, and some logging formatting cleanup.
  9. ::                  1.4.3 / Tweaked logging to only display exclamation point if there was an error
  10. ::                        / Tweaked logging to display time correctly (no extra spaces)
  11. ::                  1.4.2 / Some logging tweaks
  12. ::                  1.4.1 / Some logging tweaks
  13. ::                  1.4   + Added quotes around SOURCE variable that were missing in a couple places
  14. ::                  1.3   * Fixed backup archiving - wasn't rotating properly on network paths. We use pushd to get around this
  15. ::                        - Added "-s" option to show job options that the script WOULD execute with
  16. ::                        - Major overhaul of code order and logic. Stuff should break less now.
  17. ::                        - Many fixes to exclusions file checking
  18. ::                  1.2   - Fixed problem with cleaning backups. Now cleans staging area and long-term destination area.
  19. ::                          Normally an archive (-a) switch cleans the staging area, but now the -c switch does as well, just in case.
  20. ::                        - Also fixed issue with forfiles.exe not being able to read UNC paths. We use pushd to get around this.
  21. ::                          Pushd auto-assigns the next available drive letter to a UNC path, then discards it when we use popd.
  22. ::                  1.1   - Added option to use an exclude file to specify files/folders to exclude from the backup
  23. ::                  1.0b    Some tweaks to logging
  24. ::                  1.0     Initial write
  25.  
  26. :: Notes:           My intention for this script was to keep the logic controlling schedules, backup type, etc out of the script and
  27. ::                  let an invoking program handle it (e.g. Task Scheduler). You simply run this script with a flag to perform an action.
  28. ::                  If you want to schedule monthly backups, purge old files, etc, just set up task scheduler jobs for those tasks,
  29. ::                  where each job calls the script with a different flag.
  30.  
  31. :: Usage:           Run this script without any flags for a list of possible actions. Run it with a flag to perform that action.
  32. ::                  Flags:
  33. ::                   -f   create full backup
  34. ::                   -d   create differential backup (full backup must already exist)
  35. ::                   -r   restore from a backup (extracts to your staging area)
  36. ::                   -a   archive (close out/rotate) the current backup set. This:
  37. ::                        1. moves all .7z files in the %DESTINATION% into a folder named with the current date
  38. ::                        2. deletes all .7z files from the staging area
  39. ::                   -c   clean up (delete) old backup sets from staging and destination. If you specify a number
  40. ::                        of days after the command it will run automatically without any confirmation. Be careful with this!
  41. ::                   -s   show job options (show what the variables are set to)
  42.  
  43. :: Important:       If you want to set this script up in Windows Task Scheduler, be aware that Task Scheduler
  44. ::                  can't use mapped network drives (X:\, Z:\, etc) when it is set to "Run even if user isn't logged on."
  45. ::                  The task will simply fail to do anything (because Scheduler can't see the drives). To work around this use
  46. ::                  UNC paths instead (\\server\backup_folder etc) for your source, destination, and staging areas.
  47.  
  48. :: TODO:           
  49. ::                  1. Add md5sum checksum file in the backup directory (md5sum each full and diff and store in a file)
  50.  
  51.  
  52. :: Prep
  53. @echo off
  54. SETLOCAL
  55. set VERSION=1.4.6
  56. set SCRIPT_NAME=%0%
  57.  
  58. :::::::::::::::
  59. :: VARIABLES ::
  60. :::::::::::::::
  61. :: Rules for variables:
  62. ::  * NO quotes!                       (bad:  "c:\directory\path"       )
  63. ::  * NO trailing slashes on the path! (bad:   c:\directory\            )
  64. ::  * Spaces are okay                  (okay:  c:\my folder\with spaces )
  65. ::  * Network paths are okay           (okay:  \\server\share name      )
  66. ::                                     (okay:  \\172.16.1.5\share name  )
  67.  
  68. :: Specify the folder you want to back up here.
  69. set SOURCE=C:\Users\vocatus\SuperImportantDocuments
  70.  
  71. :: Work area where everything is stored while compressing. Should be a fast drive or something that can handle a lot of writes
  72. :: Recommend not using a network share unless it's Gigabit or faster.
  73. set STAGING=P:\backup_staging
  74.  
  75. :: This is the final, long-term destination for your backup after it is compressed.
  76. set DESTINATION=\\CoolServerName\backup_vocatus\folder with spaces\SuperImportantDocuments
  77.  
  78. :: If you want to customize the prefix of the backup files, do so here. Don't use any special characters (like underscores)
  79. :: The script automatically suffixes an underscore to this name. Recommend not changing this unless you really need to.
  80. ::  * Spaces are NOT OKAY to use here!
  81. set BACKUP_PREFIX=backup
  82.  
  83. :: OPTIONAL: If you want to exclude some files or folders, you can specify your exclude file here. The exclude file is a list of
  84. :: files or folders (wildcards in the form of * are allowed and recommended) to exclude.
  85. :: If you specify a file here and the script can't find it, it will abort.
  86. :: If you leave this blank, the script won't ignore any files.
  87. set EXCLUSIONS_FILE=C:\Users\vocatus\root\Scripts\sysadmin\backup_differential_excludes.txt
  88.  
  89. :: Log settings. Max size is how big (in bytes) the log can be before it is archived. 1048576 bytes is one megabyte
  90. set LOGPATH=%SystemDrive%\Logs
  91. set LOGFILE=%COMPUTERNAME%_%BACKUP_PREFIX%_differential.log
  92. set LOG_MAX_SIZE=2097152
  93.  
  94. :: Location of 7-Zip and forfiles.exe
  95. set SEVENZIP="C:\Program Files\7-Zip\7z.exe"
  96. set FORFILES=%WINDIR%\system32\forfiles.exe
  97.  
  98. :: Don't touch anything below this line. If you do, you will break something.
  99. set CUR_DATE=%DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%
  100. set JOB_TYPE=%1
  101. set JOB_ERROR=0
  102. set DAYS=%2
  103. set RESTORE_TYPE=NUL
  104.  
  105.  
  106. ::::::::::::::::::::::::::::
  107. :: JOB TYPE DETERMINATION ::
  108. ::::::::::::::::::::::::::::
  109. :job_type_determination
  110. if '%JOB_TYPE%'=='' set JOB_TYPE=help
  111. if '%JOB_TYPE%'=='/?' set JOB_TYPE=help
  112. if '%JOB_TYPE%'=='-?' set JOB_TYPE=help
  113. if '%JOB_TYPE%'=='-h' set JOB_TYPE=help
  114. if '%JOB_TYPE%'=='--help' set JOB_TYPE=help
  115. if /i '%1'=='/f' set JOB_TYPE=full
  116. if /i '%1'=='-f' set JOB_TYPE=full
  117. if /i '%1'=='/d' set JOB_TYPE=differential
  118. if /i '%1'=='-d' set JOB_TYPE=differential
  119. if /i '%1'=='/r' set JOB_TYPE=restore
  120. if /i '%1'=='-r' set JOB_TYPE=restore
  121. if /i '%1'=='/a' set JOB_TYPE=archive_backup_set
  122. if /i '%1'=='-a' set JOB_TYPE=archive_backup_set
  123. if /i '%1'=='/c' set JOB_TYPE=cleanup_archives
  124. if /i '%1'=='-c' set JOB_TYPE=cleanup_archives
  125. if /i '%1'=='/s' goto show_options
  126. if /i '%1'=='-s' goto show_options
  127. :: If none of the above were specified then show the help screen
  128. if %JOB_TYPE%==help (
  129.     echo.
  130.     echo   %SCRIPT_NAME% v%VERSION%
  131.     echo.
  132.     echo   Usage: %SCRIPT_NAME% ^< -f ^| -d ^| -r ^| -a ^| -c ^[days^] ^>
  133.     echo.
  134.     echo   Flags:
  135.     echo    -f:  create a full backup
  136.     echo    -d:  create a differential backup ^(requires an existing full backup^)
  137.     echo    -r:  restore from a backup ^(extracts to %STAGING%\%BACKUP_PREFIX%_restore^)
  138.     echo    -a:  archive the current backup set. This will:
  139.     echo           1. move all .7z files located in:
  140.     echo              %DESTINATION%
  141.     echo              into a dated archive folder.
  142.     echo           2. purge ^(delete^) all copies in the staging area ^(%STAGING%^)
  143.     echo    -c:  clean ^(AKA delete^) archived backup sets from staging and long-term storage.
  144.     echo         Optionally specify number of days to run automatically. Be careful with this!
  145.     echo         Note that this requires a previously-archived backup set ^(-a option^)
  146.     echo    -s:  show job options ^(show what parameters the script WOULD execute with^)
  147.     echo.
  148.     echo   Edit this script before running it to specify your source, destination, and work directories.
  149.     goto end
  150.     )
  151.  
  152.  
  153. :::::::::::::::::::::::
  154. :: LOG FILE HANDLING ::
  155. :::::::::::::::::::::::
  156. :log
  157. :: Make the logfile if it doesn't exist
  158. if not exist %LOGPATH% mkdir %LOGPATH%
  159. if not exist %LOGPATH%\%LOGFILE% echo. > %LOGPATH%\%LOGFILE%
  160.  
  161. :: Check log size. If it's less than our max, then go ahead and get started
  162. for %%R in (%LOGPATH%\%LOGFILE%) do if %%~zR LSS %LOG_MAX_SIZE% goto required_files_check
  163.  
  164. :: If the log was too big, go ahead and rotate it.
  165. pushd %LOGPATH% 2>&1
  166. del /F %LOGFILE%.ancient 2>NUL
  167. rename %LOGFILE%.oldest %LOGFILE%.ancient 2>NUL
  168. rename %LOGFILE%.older %LOGFILE%.oldest 2>NUL
  169. rename %LOGFILE%.old %LOGFILE%.older 2>NUL
  170. rename %LOGFILE% %LOGFILE%.old 2>NUL
  171. popd
  172.  
  173.  
  174. ::::::::::::::::::::::::::
  175. :: REQUIRED FILES CHECK ::
  176. ::::::::::::::::::::::::::
  177. :required_files_check
  178. :: Make sure we can find 7-Zip
  179. IF NOT EXIST %SEVENZIP% (
  180.         echo %TIME%   ERROR: Couldn't find 7z.exe when script was invoked.>> %LOGPATH%\%LOGFILE%
  181.         cls
  182.         color 0c
  183.         echo.
  184.         echo  ERROR:
  185.         echo.
  186.         echo  Cannot find 7z.exe. You must edit this script
  187.         echo  and specify the location of 7-Zip before continuing.
  188.         echo.
  189.         echo  Script tried to find it here:
  190.         echo  %SEVENZIP%
  191.         echo.
  192.         pause
  193.         color
  194.         cls
  195.         goto end
  196.         )
  197. :: Make sure we can find forfiles.exe
  198. IF NOT EXIST %FORFILES% (
  199.         echo %TIME%   ERROR: Couldn't find forfiles.exe when script was invoked.>> %LOGPATH%\%LOGFILE%
  200.         cls
  201.         color 0c
  202.         echo.
  203.         echo  ERROR:
  204.         echo.
  205.         echo  Cannot find forfiles.exe. You must edit this script
  206.         echo  and specify the location of forfiles.exe before continuing.
  207.         echo.
  208.         echo  Script tried to find it here:
  209.         echo  %FORFILES%
  210.         echo.
  211.         pause
  212.         color
  213.         cls
  214.         goto end
  215.         )
  216.  
  217.  
  218. ::::::::::::::::::::
  219. :: DECISION POINT ::
  220. ::::::::::::::::::::
  221. :decision_point
  222. if '%JOB_TYPE%'=='full' goto %JOB_TYPE%
  223. if '%JOB_TYPE%'=='differential' goto %JOB_TYPE%
  224. if '%JOB_TYPE%'=='restore' goto %JOB_TYPE%
  225. if '%JOB_TYPE%'=='archive_backup_set' goto %JOB_TYPE%
  226. if '%JOB_TYPE%'=='cleanup_archives' goto %JOB_TYPE%
  227. goto end
  228.  
  229.  
  230. ::::::::::::::::::::::
  231. :: SHOW JOB OPTIONS ::
  232. ::::::::::::::::::::::
  233. :show_options
  234. echo.
  235. echo  Current configuration:
  236. echo.
  237. echo   Script Version:       %VERSION%
  238. echo   Source:               %SOURCE%
  239. echo   Destination:          %DESTINATION%
  240. echo   Staging area:         %STAGING%
  241. echo   Exclusions file:      %EXCLUSIONS_FILE%
  242. echo   Backup prefix:        %BACKUP_PREFIX%
  243. echo   Restores unpacked to: %STAGING%\%BACKUP_PREFIX%_restore
  244. echo   Log file:             %LOGPATH%\%LOGFILE%
  245. echo   Log max size:         %LOG_MAX_SIZE% bytes
  246. echo.
  247. echo  Edit this script with a text editor to customize these options.
  248. echo.
  249. goto end
  250.  
  251.  
  252. ::::::::::::::::::::::::
  253. :: CREATE FULL BACKUP ::
  254. ::::::::::::::::::::::::
  255. :full
  256. :: Check for an exclude file and make sure it exists.
  257. if '%EXCLUSIONS_FILE%'=='' goto full_go
  258. IF NOT EXIST %EXCLUSIONS_FILE% (
  259.         echo.
  260.         echo %TIME%   ERROR: An exclusions file was specified but couldn't be found:>> %LOGPATH%\%LOGFILE%
  261.         echo                %EXCLUSIONS_FILE%>> %LOGPATH%\%LOGFILE%
  262.         echo %TIME%   ERROR: An exclusions file was specified but couldn't be found:
  263.         echo                %EXCLUSIONS_FILE%
  264.         goto end
  265.         )
  266. :full_go
  267. echo.
  268. echo.>> %LOGPATH%\%LOGFILE%
  269. echo --------------------------------------------------------------------------------------------------->> %LOGPATH%\%LOGFILE%
  270. echo  Differential Backup Script v%VERSION% - initialized %CUR_DATE% at%TIME% by %USERDOMAIN%\%USERNAME%>> %LOGPATH%\%LOGFILE%
  271. echo.>> %LOGPATH%\%LOGFILE%
  272. echo  Script location:  %SCRIPT_NAME%>> %LOGPATH%\%LOGFILE%
  273. echo.>> %LOGPATH%\%LOGFILE%
  274. echo  Job Options>> %LOGPATH%\%LOGFILE%
  275. echo   Job type:        Full backup>> %LOGPATH%\%LOGFILE%
  276. echo   Source:          %SOURCE%>> %LOGPATH%\%LOGFILE%
  277. echo   Destination:     %DESTINATION%>> %LOGPATH%\%LOGFILE%
  278. echo   Staging area:    %STAGING%>> %LOGPATH%\%LOGFILE%
  279. echo   Exclusions file: %EXCLUSIONS_FILE%>> %LOGPATH%\%LOGFILE%
  280. echo   Backup prefix:   %BACKUP_PREFIX%>> %LOGPATH%\%LOGFILE%
  281. echo   Log location:    %LOGPATH%\%LOGFILE%>> %LOGPATH%\%LOGFILE%
  282. echo   Log max size:    %LOG_MAX_SIZE% bytes>> %LOGPATH%\%LOGFILE%
  283. echo --------------------------------------------------------------------------------------------------->> %LOGPATH%\%LOGFILE%
  284. echo.>> %LOGPATH%\%LOGFILE%
  285. echo %TIME%   Performing full backup of %SOURCE%...>> %LOGPATH%\%LOGFILE%
  286. echo %TIME%   Performing full backup of %SOURCE%...
  287.  
  288. :: Build archive
  289. echo.
  290. echo %TIME%   Building archive in staging area %STAGING%...>> %LOGPATH%\%LOGFILE%
  291. echo %TIME%   Building archive in staging area %STAGING%...
  292. echo.>> %LOGPATH%\%LOGFILE%
  293. echo [Beginning of 7zip output]>> %LOGPATH%\%LOGFILE% 2>&1
  294. if not '%EXCLUSIONS_FILE%'=='' %SEVENZIP% a "%STAGING%\%BACKUP_PREFIX%_full.7z" "%SOURCE%" -xr@"%EXCLUSIONS_FILE%" >> %LOGPATH%\%LOGFILE%
  295. if '%EXCLUSIONS_FILE%'=='' %SEVENZIP% a "%STAGING%\%BACKUP_PREFIX%_full.7z" "%SOURCE%" >> %LOGPATH%\%LOGFILE%
  296. echo [End of 7zip output]>> %LOGPATH%\%LOGFILE% 2>&1
  297. echo.>> %LOGPATH%\%LOGFILE%
  298. echo.
  299.  
  300. :: Report on the build
  301. if %ERRORLEVEL%==0 (
  302.         echo %TIME%   Archive built successfully.>> %LOGPATH%\%LOGFILE%
  303.         echo %TIME%   Archive built successfully.
  304.         )
  305. if not %ERRORLEVEL%==0 (
  306.         set JOB_ERROR=1
  307.         echo %TIME% ! Archive built with errors.>> %LOGPATH%\%LOGFILE%
  308.         echo %TIME% ! Archive built with errors.
  309.         )
  310. :: Upload to destination
  311. echo.
  312. echo %TIME%   Uploading %BACKUP_PREFIX%_full.7z to %DESTINATION%...>> %LOGPATH%\%LOGFILE%
  313. echo %TIME%   Uploading %BACKUP_PREFIX%_full.7z to %DESTINATION%...
  314. echo.
  315. echo.>> %LOGPATH%\%LOGFILE%
  316. xcopy "%STAGING%\%BACKUP_PREFIX%_full.7z" "%DESTINATION%\" /Q /J /Y /Z >> %LOGPATH%\%LOGFILE%
  317. echo.>> %LOGPATH%\%LOGFILE%
  318.  
  319. :: Report on the upload
  320. if %ERRORLEVEL%==0 (
  321.         echo %TIME%   Uploaded full backup to %DESTINATION% successfully.>> %LOGPATH%\%LOGFILE%
  322.         echo %TIME%   Uploaded full backup to %DESTINATION% successfully.
  323.         ) ELSE (
  324.         set JOB_ERROR=1
  325.         echo %TIME% ! Upload of full backup to %DESTINATION% failed.>> %LOGPATH%\%LOGFILE%
  326.         echo %TIME% ! Upload of full backup to %DESTINATION% failed.
  327.         )
  328.  
  329. goto done
  330.  
  331.  
  332. ::::::::::::::::::::::::::::::::
  333. :: CREATE DIFFERENTIAL BACKUP ::
  334. ::::::::::::::::::::::::::::::::
  335. :differential
  336. :: Check for an exclude file and make sure it exists.
  337. if '%EXCLUSIONS_FILE%'=='' goto differential_go
  338. IF NOT EXIST %EXCLUSIONS_FILE% (
  339.         echo %TIME%   An exclusions file was specified but couldn't be found. Aborting.>> %LOGPATH%\%LOGFILE%
  340.         echo           Looked here: %EXCLUSIONS_FILE%>> %LOGPATH%\%LOGFILE%
  341.         echo %TIME%   An exclusions file was specified but couldn't be found. Aborting.
  342.         echo           Looked here: %EXCLUSIONS_FILE%
  343.         goto end
  344.         )
  345. :differential_go
  346. echo.>> %LOGPATH%\%LOGFILE%
  347. echo --------------------------------------------------------------------------------------------------->> %LOGPATH%\%LOGFILE%
  348. echo  Differential Backup Script v%VERSION% - initialized %CUR_DATE% at%TIME% by %USERDOMAIN%\%USERNAME%>> %LOGPATH%\%LOGFILE%
  349. echo.>> %LOGPATH%\%LOGFILE%
  350. echo  Script location:  %SCRIPT_NAME%>> %LOGPATH%\%LOGFILE%
  351. echo.>> %LOGPATH%\%LOGFILE%
  352. echo  Job Options>> %LOGPATH%\%LOGFILE%
  353. echo   Job type:        Differential backup>> %LOGPATH%\%LOGFILE%
  354. echo   Source:          %SOURCE%>> %LOGPATH%\%LOGFILE%
  355. echo   Destination:     %DESTINATION%>> %LOGPATH%\%LOGFILE%
  356. echo   Staging area:    %STAGING%>> %LOGPATH%\%LOGFILE%
  357. echo   Exclusions file: %EXCLUSIONS_FILE%>> %LOGPATH%\%LOGFILE%
  358. echo   Backup prefix:   %BACKUP_PREFIX%>> %LOGPATH%\%LOGFILE%
  359. echo   Log location:    %LOGPATH%\%LOGFILE%>> %LOGPATH%\%LOGFILE%
  360. echo   Log max size:    %LOG_MAX_SIZE% bytes>> %LOGPATH%\%LOGFILE%
  361. echo --------------------------------------------------------------------------------------------------->> %LOGPATH%\%LOGFILE%
  362. echo.>> %LOGPATH%\%LOGFILE%
  363. echo.
  364. :: Check for full backup existence
  365. if not exist "%STAGING%\%BACKUP_PREFIX%_full.7z" (
  366.         set JOB_ERROR=1
  367.         echo %TIME% ! ERROR: Couldn't find full backup file ^(%BACKUP_PREFIX%_full.7z^). You must create a full backup before a differential can be created.>> %LOGPATH%\%LOGFILE%
  368.         echo %TIME% ! ERROR: Couldn't find full backup file ^(%BACKUP_PREFIX%_full.7z^). You must create a full backup before a differential can be created.
  369.         goto end
  370.         ) ELSE (
  371.         :: Backup existed, so go ahead
  372.         echo %TIME%   Performing differential backup of %SOURCE%...>> %LOGPATH%\%LOGFILE%
  373.         echo %TIME%   Performing differential backup of %SOURCE%...
  374.         )
  375.        
  376. :: Build archive
  377. :differential_build
  378. echo.
  379. echo %TIME%   Building archive in staging area %STAGING%...>> %LOGPATH%\%LOGFILE%
  380. echo %TIME%   Building archive in staging area %STAGING%...
  381. echo.>> %LOGPATH%\%LOGFILE%
  382. echo [Beginning of 7zip output]>> %LOGPATH%\%LOGFILE% 2>&1
  383. if not '%EXCLUSIONS_FILE%'=='' %SEVENZIP% u "%STAGING%\%BACKUP_PREFIX%_full.7z" "%SOURCE%" -ms=off -mx=9 -xr@"%EXCLUSIONS_FILE%" -t7z -u- -up0q3r2x2y2z0w2!"%STAGING%\%BACKUP_PREFIX%_differential_%CUR_DATE%.7z" >> %LOGPATH%\%LOGFILE% 2>&1
  384. if '%EXCLUSIONS_FILE%'=='' %SEVENZIP% u "%STAGING%\%BACKUP_PREFIX%_full.7z" "%SOURCE%" -ms=off -mx=9 -t7z -u- -up0q3r2x2y2z0w2!"%STAGING%\%BACKUP_PREFIX%_differential_%CUR_DATE%.7z" >> %LOGPATH%\%LOGFILE% 2>&1
  385. echo [End of 7zip output]>> %LOGPATH%\%LOGFILE% 2>&1
  386. echo.>> %LOGPATH%\%LOGFILE%
  387. echo.
  388. :: Report on the build
  389. if %ERRORLEVEL%==0 (
  390.         echo %TIME%   Archive built successfully.>> %LOGPATH%\%LOGFILE%
  391.         echo %TIME%   Archive built successfully.
  392.         )
  393. if not %ERRORLEVEL%==0 (
  394.         set JOB_ERROR=1
  395.         echo %TIME% ! Archive built with errors.>> %LOGPATH%\%LOGFILE%
  396.         echo %TIME% ! Archive built with errors.
  397.         )
  398.  
  399.  
  400. :: Upload to destination
  401. echo.
  402. echo %TIME%   Uploading %BACKUP_PREFIX%_differential_%CUR_DATE%.7z to %DESTINATION%... >> %LOGPATH%\%LOGFILE%
  403. echo %TIME%   Uploading %BACKUP_PREFIX%_differential_%CUR_DATE%.7z to %DESTINATION%...
  404. echo.>> %LOGPATH%\%LOGFILE%
  405. xcopy "%STAGING%\%BACKUP_PREFIX%_differential_%CUR_DATE%.7z" "%DESTINATION%\" /Q /J /Y /Z >> %LOGPATH%\%LOGFILE%
  406. echo.>> %LOGPATH%\%LOGFILE%
  407. :: Report on the upload
  408. if %ERRORLEVEL%==0 (
  409.         echo %TIME%   Uploaded differential file successfully.>> %LOGPATH%\%LOGFILE%
  410.         echo %TIME%   Uploaded differential file successfully.
  411.         )
  412.  
  413. if not %ERRORLEVEL%==0 (
  414.         set JOB_ERROR=1
  415.         echo %TIME% ! Upload of differential file failed.>> %LOGPATH%\%LOGFILE%
  416.         echo %TIME% ! Upload of differential file failed.
  417.         )
  418.  
  419. goto done
  420.  
  421.  
  422. :::::::::::::::::::::::::::
  423. :: RESTORE FROM A BACKUP ::
  424. :::::::::::::::::::::::::::
  425. :restore
  426. echo.
  427. echo  Restoring from a backup set.
  428. echo.
  429. echo   These backups are available:
  430. echo.
  431. dir /B /A:-D "%STAGING%" 2>NUL
  432. echo.
  433. echo  Enter the filename to restore from exactly as it appears above.
  434. echo  ^(Note: archived backup sets are not shown^)
  435. echo.
  436. :restore_menu
  437. set BACKUP_FILE=
  438. set /p BACKUP_FILE=Filename:
  439. if %BACKUP_FILE%==exit goto end
  440. echo.
  441. :: Make sure user didn't fat-finger the file name
  442. if not exist "%STAGING%\%BACKUP_FILE%" (
  443.         echo  ! ERROR: That file wasn^'t found. Check your typing and try again. && echo. && goto restore_menu
  444.         goto restore_menu
  445.         )
  446.  
  447. set CHOICE=y
  448. echo  ! Selected file '%BACKUP_FILE%'
  449. echo.
  450. set /p CHOICE=Is this correct [y]?:
  451.     if not %CHOICE%==y echo  Going back to menu... && goto restore_menu
  452. echo.
  453. echo  Great. Press any key to get started.
  454. pause >NUL
  455. echo  ! Starting restoration at%TIME% on %CUR_DATE%
  456. echo    This might take a while, be patient...
  457.  
  458. :: Test if we're doing a full or differential restore.
  459. if %BACKUP_FILE%==%BACKUP_PREFIX%_full.7z set RESTORE_TYPE=full
  460. if not %BACKUP_FILE%==%BACKUP_PREFIX%_full.7z set RESTORE_TYPE=differential
  461.  
  462.  
  463. :restore_go
  464. echo.>> %LOGPATH%\%LOGFILE%
  465. echo --------------------------------------------------------------------------------------------------->> %LOGPATH%\%LOGFILE%
  466. echo  Differential Backup Script v%VERSION% - initialized %CUR_DATE% at%TIME% by %USERDOMAIN%\%USERNAME%>> %LOGPATH%\%LOGFILE%
  467. echo.>> %LOGPATH%\%LOGFILE%
  468. echo  Script location:  %SCRIPT_NAME%>> %LOGPATH%\%LOGFILE%
  469. echo.>> %LOGPATH%\%LOGFILE%
  470. echo  Job Options>> %LOGPATH%\%LOGFILE%
  471. echo   Job type:        %RESTORE_TYPE% restore>> %LOGPATH%\%LOGFILE%
  472. echo   Source:          %STAGING%\%BACKUP_PREFIX%_full.7z>> %LOGPATH%\%LOGFILE%
  473. echo   Destination:     %STAGING%\%BACKUP_PREFIX%\>> %LOGPATH%\%LOGFILE%
  474. echo   Staging area:    %STAGING%>> %LOGPATH%\%LOGFILE%
  475. echo   Exclusions file: %EXCLUSIONS_FILE%>> %LOGPATH%\%LOGFILE%
  476. echo   Backup prefix:   %BACKUP_PREFIX%>> %LOGPATH%\%LOGFILE%
  477. echo   Log location:    %LOGPATH%\%LOGFILE%>> %LOGPATH%\%LOGFILE%
  478. echo   Log max size:    %LOG_MAX_SIZE% bytes>> %LOGPATH%\%LOGFILE%
  479. echo --------------------------------------------------------------------------------------------------->> %LOGPATH%\%LOGFILE%
  480. echo.
  481. :: Detect our backup type and inform the user
  482. if %RESTORE_TYPE%==differential (
  483.         echo %TIME%   Restoring from differential backup. Will unpack full backup then differential.>> %LOGPATH%\%LOGFILE%
  484.         echo %TIME%   Restoring from differential backup. Will unpack full backup then differential.
  485.         )
  486. if %RESTORE_TYPE%==full (
  487.         echo %TIME%   Restoring from full backup.>> %LOGPATH%\%LOGFILE%
  488.         echo %TIME%   Restoring from full backup.
  489.         echo %TIME%   Unpacking full backup...>> %LOGPATH%\%LOGFILE%
  490.         echo %TIME%   Unpacking full backup...
  491.         )
  492.  
  493. :: Start the restoration
  494. echo.>> %LOGPATH%\%LOGFILE%
  495. echo.
  496. echo [Beginning of 7zip output]>> %LOGPATH%\%LOGFILE% 2>&1
  497. %SEVENZIP% x "%STAGING%\%BACKUP_PREFIX%_full.7z" -y -o"%STAGING%\%BACKUP_PREFIX%_restore\">> %LOGPATH%\%LOGFILE% 2>&1
  498. echo [End of 7zip output]>> %LOGPATH%\%LOGFILE% 2>&1
  499. :: Report on the unpack
  500. if %ERRORLEVEL%==0 (
  501.         echo %TIME%   Full backup unpacked successfully.>> %LOGPATH%\%LOGFILE%
  502.         echo %TIME%   Full backup unpacked successfully.
  503.         )
  504. if not %ERRORLEVEL%==0 (
  505.         set JOB_ERROR=1
  506.         echo %TIME% ! Full backup unpacked with errors.>> %LOGPATH%\%LOGFILE%
  507.         echo %TIME% ! Full backup unpacked with errors.
  508.         )
  509. :: If we're just doing a full restore (no differential), then go to the end
  510. if %RESTORE_TYPE%==full goto done
  511.        
  512. :: Now we unpack our differential file
  513. echo.
  514. echo %TIME%   Unpacking differential file %BACKUP_FILE%...>> %LOGPATH%\%LOGFILE%
  515. echo %TIME%   Unpacking differential file %BACKUP_FILE%...
  516. echo.>> %LOGPATH%\%LOGFILE%
  517. echo [Beginning of 7zip output]>> %LOGPATH%\%LOGFILE% 2>&1
  518. %SEVENZIP% x "%STAGING%\%BACKUP_FILE%" -aoa -y -o"%STAGING%\%BACKUP_PREFIX%_restore\">> %LOGPATH%\%LOGFILE% 2>&1
  519. echo [End of 7zip output]>> %LOGPATH%\%LOGFILE% 2>&1
  520. echo.
  521. :: Report on the unpack
  522. if %ERRORLEVEL%==0 (
  523.         echo %TIME%   Differential file unpacked successfully.>> %LOGPATH%\%LOGFILE%
  524.         echo %TIME%   Differential file unpacked successfully.
  525.         ) ELSE (
  526.         :: Something broke!
  527.         set JOB_ERROR=1
  528.         echo %TIME% ! Differential file unpacked with errors.>> %LOGPATH%\%LOGFILE%
  529.         echo %TIME% ! Differential file unpacked with errors.
  530.         )
  531. goto done
  532.  
  533.  
  534. ::::::::::::::::::::::::
  535. :: ARCHIVE BACKUP SET :: aka rotate backups
  536. ::::::::::::::::::::::::
  537. :archive_backup_set
  538. echo.>> %LOGPATH%\%LOGFILE%
  539. echo --------------------------------------------------------------------------------------------------->> %LOGPATH%\%LOGFILE%
  540. echo  Differential Backup Script v%VERSION% - initialized %CUR_DATE% at%TIME% by %USERDOMAIN%\%USERNAME%>> %LOGPATH%\%LOGFILE%
  541. echo.>> %LOGPATH%\%LOGFILE%
  542. echo  Script location:  %SCRIPT_NAME%>> %LOGPATH%\%LOGFILE%
  543. echo.>> %LOGPATH%\%LOGFILE%
  544. echo  Job Options>> %LOGPATH%\%LOGFILE%
  545. echo   Job type:        Archive/rotate backup set>> %LOGPATH%\%LOGFILE%
  546. echo   Source:          %SOURCE%>> %LOGPATH%\%LOGFILE%
  547. echo   Destination:     %DESTINATION%>> %LOGPATH%\%LOGFILE%
  548. echo   Staging area:    %STAGING%>> %LOGPATH%\%LOGFILE%
  549. echo   Exclusions file: %EXCLUSIONS_FILE%>> %LOGPATH%\%LOGFILE%
  550. echo   Backup prefix:   %BACKUP_PREFIX%>> %LOGPATH%\%LOGFILE%
  551. echo   Log location:    %LOGPATH%\%LOGFILE%>> %LOGPATH%\%LOGFILE%
  552. echo   Log max size:    %LOG_MAX_SIZE% bytes>> %LOGPATH%\%LOGFILE%
  553. echo --------------------------------------------------------------------------------------------------->> %LOGPATH%\%LOGFILE%
  554. echo.>> %LOGPATH%\%LOGFILE%
  555. echo %TIME%   Archiving current backup set to %DESTINATION%\%CUR_DATE%_%BACKUP_PREFIX%_set.>> %LOGPATH%\%LOGFILE%
  556. echo %TIME%   Archiving current backup set to %DESTINATION%\%CUR_DATE%_%BACKUP_PREFIX%_set.
  557. :: Final destination: Make directory, move files
  558. pushd "%DESTINATION%"
  559. mkdir %CUR_DATE%_%BACKUP_PREFIX%_set >> %LOGPATH%\%LOGFILE%
  560. move /Y *.* %CUR_DATE%_%BACKUP_PREFIX%_set >> %LOGPATH%\%LOGFILE%
  561. popd
  562. echo.
  563. echo %TIME%   Deleting all copies in the staging area...>> %LOGPATH%\%LOGFILE%
  564. echo %TIME%   Deleting all copies in the staging area...
  565. :: Staging area: Delete old files
  566. del /Q /F "%STAGING%\*.7z">> %LOGPATH%\%LOGFILE%
  567. echo.>> %LOGPATH%\%LOGFILE%
  568. echo.
  569.  
  570. :: Report
  571. echo.>> %LOGPATH%\%LOGFILE%
  572. echo %TIME%   Backup set archived. All unarchived files in staging area were deleted.>> %LOGPATH%\%LOGFILE%
  573. echo %TIME%   Backup set archived. All unarchived files in staging area were deleted.
  574. echo.>> %LOGPATH%\%LOGFILE%
  575. goto done
  576.  
  577.  
  578. :::::::::::::::::::::::::::::::::::
  579. :: CLEAN UP ARCHIVED BACKUP SETS :: aka delete old sets
  580. :::::::::::::::::::::::::::::::::::
  581. :cleanup_archives
  582. IF NOT '%DAYS%'=='' goto cleanup_archives_go
  583.  
  584. :: List the backup sets
  585. :cleanup_archives_list
  586. echo.
  587. echo CURRENT BACKUP SETS:
  588. echo.
  589. echo IN STAGING          : ^(%STAGING%^)
  590. echo ---------------------
  591. dir /B /A:D "%STAGING%" 2>&1
  592. echo.
  593. echo.
  594. echo IN LONG-TERM STORAGE: ^(%DESTINATION%^)
  595. echo ---------------------
  596. dir /B /A:D "%DESTINATION%" 2>&1
  597. echo.
  598. :cleanup_archives_list2
  599. echo.
  600. set DAYS=180
  601. echo Delete backup sets older than how many days? ^(you will be prompted for confirmation^)
  602. set /p DAYS=[%DAYS%]?:
  603. if %DAYS%==exit goto end
  604. echo.
  605. :: Tell user what will happen
  606. echo THESE BACKUP SETS WILL BE DELETED:
  607. echo ----------------------------------
  608. :: List files that would match.
  609. :: We have to use PushD to get around forfiles.exe not using UNC paths. pushd automatically assigns the next free drive letter
  610. echo From staging:
  611. pushd "%STAGING%"
  612. FORFILES /D -%DAYS% /C "cmd /c IF @isdir == TRUE echo @path" 2>NUL
  613. popd
  614. echo.
  615. echo From long-term storage:
  616. pushd "%DESTINATION%"
  617. FORFILES /D -%DAYS% /C "cmd /c IF @isdir == TRUE echo @path" 2>NUL
  618. popd
  619. echo.
  620. set HMMM=n
  621. set /p HMMM=Is this okay [%HMMM%]?:
  622. if /i %HMMM%==n echo. && echo Canceled. Returning to menu. && goto cleanup_archives_list2
  623. if %DAYS%==exit goto end
  624. echo.
  625. set CHOICE=n
  626. set /p CHOICE=Are you absolutely sure [%CHOICE%]?:
  627. if not %CHOICE%==y echo. && echo Canceled. Returning to menu. && goto cleanup_archives_list2
  628. echo.
  629. echo  Okay, starting deletion.
  630.  
  631. :: Go ahead and do the cleanup.
  632. :cleanup_archives_go
  633. echo --------------------------------------------------------------------------------------------------->> %LOGPATH%\%LOGFILE%
  634. echo  Differential Backup Script v%VERSION% - initialized %CUR_DATE% at%TIME% by %USERDOMAIN%\%USERNAME%>> %LOGPATH%\%LOGFILE%
  635. echo.>> %LOGPATH%\%LOGFILE%
  636. echo  Script location:  %SCRIPT_NAME%>> %LOGPATH%\%LOGFILE%
  637. echo.>> %LOGPATH%\%LOGFILE%
  638. echo   Job type:        Delete archived backup sets older than %DAYS% days.>> %LOGPATH%\%LOGFILE%
  639. echo   Source:          %SOURCE%>> %LOGPATH%\%LOGFILE%
  640. echo   Destination:     %DESTINATION%>> %LOGPATH%\%LOGFILE%
  641. echo   Staging area:    %STAGING%>> %LOGPATH%\%LOGFILE%
  642. echo   Exclusions file: %EXCLUSIONS_FILE%>> %LOGPATH%\%LOGFILE%
  643. echo   Backup prefix:   %BACKUP_PREFIX%>> %LOGPATH%\%LOGFILE%
  644. echo   Log location:    %LOGPATH%\%LOGFILE%>> %LOGPATH%\%LOGFILE%
  645. echo   Log max size:    %LOG_MAX_SIZE% bytes>> %LOGPATH%\%LOGFILE%
  646. echo --------------------------------------------------------------------------------------------------->> %LOGPATH%\%LOGFILE%
  647. echo.>> %LOGPATH%\%LOGFILE%
  648. echo.
  649. echo %TIME%   Deleting backup sets that are older than %DAYS% days...>> %LOGPATH%\%LOGFILE%
  650. echo %TIME%   Deleting backup sets that are older than %DAYS% days...
  651.  
  652. :: This cleans out the staging area.
  653. :: First FORFILES command tells the logfile what will get deleted. Second command actually deletes.
  654. pushd "%STAGING%"
  655. FORFILES /D -%DAYS% /C "cmd /c IF @isdir == TRUE echo @path" >> %LOGPATH%\%LOGFILE%
  656. FORFILES /S /D -%DAYS% /C "cmd /c IF @isdir == TRUE rmdir /S /Q @path"
  657. popd
  658.  
  659. :: This cleans out the destination / long-term storage area.
  660. :: First FORFILES command tells the logfile what will get deleted. Second command actually deletes.
  661. pushd "%DESTINATION%"
  662. FORFILES /D -%DAYS% /C "cmd /c IF @isdir == TRUE echo @path" >> %LOGPATH%\%LOGFILE%
  663. FORFILES /S /D -%DAYS% /C "cmd /c IF @isdir == TRUE rmdir /S /Q @path"
  664. popd
  665.  
  666. echo.
  667. :: Report on the cleanup
  668. if %ERRORLEVEL%==0 (
  669.         echo %TIME%   Cleanup completed successfully.>> %LOGPATH%\%LOGFILE%
  670.         echo %TIME%   Cleanup completed successfully.
  671.         )
  672. if not %ERRORLEVEL%==0 (
  673.         set JOB_ERROR=1
  674.         echo %TIME% ! Cleanup completed with errors.>> %LOGPATH%\%LOGFILE%
  675.         echo %TIME% ! Cleanup completed with errors.
  676.         )
  677. goto done
  678.  
  679.  
  680. :::::::::::::::::::::::
  681. :: COMPLETION REPORT ::
  682. :::::::::::::::::::::::
  683. :done
  684. :: One of these displays if the operation was a restore operation
  685. if %RESTORE_TYPE%==full (
  686.         echo %TIME%   Restored full backup to %STAGING%\%BACKUP_PREFIX%>> %LOGPATH%\%LOGFILE%
  687.         echo %TIME%   Restored full backup to %STAGING%\%BACKUP_PREFIX%
  688.         )
  689.  
  690. if %RESTORE_TYPE%==differential (
  691.         echo.
  692.         echo %TIME%   Restored full and differential backup to %STAGING%\%BACKUP_PREFIX%>> %LOGPATH%\%LOGFILE%
  693.         echo %TIME%   Restored full and differential backup to %STAGING%\%BACKUP_PREFIX%
  694.         )
  695.  
  696. echo.
  697. echo %TIME%   %SCRIPT_NAME% complete on %CUR_DATE% at%TIME%.>> %LOGPATH%\%LOGFILE%
  698. echo %TIME%   %SCRIPT_NAME% complete on %CUR_DATE% at%TIME%.
  699. if '%JOB_ERROR%'=='1' echo. && echo %TIME% ! Note: Script exited with errors.>> %LOGPATH%\%LOGFILE%
  700. if '%JOB_ERROR%'=='1' echo. && echo %TIME% ! Note: Script exited with errors. Maybe check the log.
  701.  
  702. :end
  703. :: Clean up our temp exclude file
  704. if exist %TEMP%\DEATH_BY_HAMSTERS.txt del /F /Q %TEMP%\DEATH_BY_HAMSTERS.txt
  705. ENDLOCAL
Add Comment
Please, Sign In to add comment