Wednesday, 27 May 2015

The best Backup Script for Windows EVARRR

Over the years I have been writing tons of these backup scripts, usually on the fly, and usually thinking – I need to make this more robust, shelving that dream for the future

 

…And now the future has come:

 

BackThisUp.cmd

cls
::
::
::====================================================
:: BackThisUp
::----------------------------------------------------
:: Put a copy of this script in any folder you want to 
:: have backed up. It creates backups to a destination
:: path (like an external harddrive) in dated folders:
::      ex: E:\Backups\20150505NameOfBackup\
::
:: You can alternatively set it up so the backup folder
:: is not dated, so that backups are just kept current:
::      ex: E:\Backups\NameOfBackup\
::
:: The tool will also provide a Restore script called
:: "RestoreThis.cmd" which will return your files to
:: where they came from.
::
:: All settings: "Name of Backup", "Backup Location", 
:: and "Dated Backups" will be requested when this 
:: script is run UNLESS those settings are predefined
:: within this script. Predefined settings will allow
:: the script to run automatically, and would be the 
:: best option for scheduled backups. 
::====================================================
::
::

@ECHO OFF
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION

cls
:: Optionally Predefined variables:
::====================================================

:: backup_name
::----------------------------------------------------
:: put whatever you want to call the backup after
:: the equal sign. Keep it short, simple, don't use 
:: special characters, and avoid spaces. 
SET backup_name=

:: backup_destination
::----------------------------------------------------
:: Put the full path of where you want the Backup 
:: folder to appear. No quotes needed, should be like
:: SET backup_destination=D:\
:: After you run the script, you will see a that the
:: backup can be found at D:\Backups\[backup_name]\...
SET backup_destination=

:: backup_date
::----------------------------------------------------
:: backup date should either be 1 or 0 where
:: 1 means there will be dates.
:: 0 means there will not be dates
::
:: *** NOTE *** A backup without a date will only 
:: backup new or updated files that don't appear in 
:: the backup folder... Because that's smart
SET backup_date=

:: backup_review
::----------------------------------------------------
:: Prompt the user to review settings and allowing 
:: the user to exit the script, otherwise, the
:: script will perform the backup without query
:: 1 means prompt for review
:: 0 means silent mode, process backup without prompt
SET backup_review=1


:: Variables
::====================================================
SET me=%~n0
SET parent=%~dp0

:: FormattedDate
::====================================================
for /f "skip=1 tokens=1-6 delims= " %%a in ('wmic path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') do (
	IF NOT "%%~f"=="" (
	    set /a FormattedDate=10000 * %%f + 100 * %%d + %%a
	    set FormattedDate=!FormattedDate:~-8,4!!FormattedDate:~-4,2!!FormattedDate:~-2,2!
	)
)

cls
:: Initialization
::====================================================
:: Ask the user to provide backup_name
::----------------------------------------------------
IF NOT DEFINED backup_name (
	ECHO No backup_name was predefined!
	ECHO ----------------------------------------------------
	ECHO put whatever you want to call the backup after
	ECHO the equal sign. Keep it short, simple, don't use 
	ECHO special characters, and avoid spaces. 
	ECHO.
	SET /P backup_name=backup_name=
)

cls
:backup_destination
:: Ask the user to provide (%backup_destination%)
::----------------------------------------------------
IF NOT DEFINED backup_destination (
	ECHO No backup_destination was predefined!
	ECHO ----------------------------------------------------
	ECHO Put the full path of where you want the Backup 
	ECHO folder to appear. No quotes needed, should be like
	ECHO SET backup_destination=D:\
	ECHO After you run the script, you will see a that the
	ECHO backup can be found at D:\Backups\NameOfBackup...
	ECHO.
	SET /P backup_destination=backup_destination=
)
if NOT EXIST "%backup_destination%" echo Backup Destination doesn't exist.&cls&SET backup_destination=&goto backup_destination
::Does string have a trailing slash? if so remove it 
IF %backup_destination:~-1%==\ SET backup_destination=%backup_destination:~0,-1%


cls
:: Ask the user to provide backup_date
::----------------------------------------------------
IF NOT DEFINED backup_date (
	ECHO No backup_date was predefined!
	ECHO ----------------------------------------------------
	ECHO backup date should either be 1 or 0 where
	ECHO 1 means there will be dates.
	ECHO 0 means there will not be dates
	ECHO.
	ECHO *** NOTE *** A backup without a date will only 
	ECHO backup new or updated files that don't appear in 
	ECHO the backup folder... Because that's smart
	ECHO.
	SET /P backup_date=backup_date=
)
REM PAUSE


cls
:: Determine Current Path (%CD%)
::====================================================
PUSHD "%~dp0" >NUL && SET root=%CD% && POPD >NUL
REM ECHO CD= %CD%
REM PAUSE

cls
:: Determine Date value (%date_path%)
::====================================================
IF /I "%backup_date%" EQU "1" (
	SET date_path=%FormattedDate% 
)
REM ECHO date_path= %date_path%
REM PAUSE


cls
:: Determine Destination Path (%backup_path%)
::====================================================
SET backup_path=%backup_destination%\Backups\%date_path%%backup_name%
REM ECHO backup_path= %backup_path%
REM PAUSE


cls
:: Review Settings                  
::====================================================
IF /I "%backup_review%" EQU "1" (
	ECHO Review Settings
	ECHO ----------------------------------------------------
	ECHO We will be backing up the files and folders from:
	ECHO %CD% 
	ECHO. 
	ECHO The backup will be saved to the following folder:
	ECHO %backup_path% 
	ECHO. 
	ECHO.
	CALL :Continue
)


:: Routines
::====================================================
REM ECHO Routines
REM PAUSE
CALL :RoboCopyComplete
CALL :CreateRestore
GOTO END


:RoboCopyComplete
::----------------------------------------------------
cls
REM ECHO RoboCopyComplete
REM PAUSE
ROBOCOPY "%CD%" "%backup_path%" /E /dcopy:T /XA:SH /XD Backups /XJD /XO /R:25 /W:15 /V
:: ROBOCOPY
:: Source Directory
:: Destination Directory
:: Copy Everything (without purge) 
:: Include Directory Timestamps
:: Exclude Hidden & System Files
:: Exclude existing Backups
:: Exclude Junction points for directories
:: Exclude Existing files if they are older
:: Retry 25 Times
:: Wait 15 Seconds before each retry
:: Use 32 threads
:: Verbose output
EXIT /B 1


:Continue
::----------------------------------------------------
set /P c=Are you sure you want to continue[Y/N]? 
IF /I "%c%" NEQ "Y" CALL :ExitBatch
EXIT /B 1


:CreateRestore
::----------------------------------------------------
@ECHO ROBOCOPY "%backup_path%" "%CD%" /E /dcopy:T /XA:SH /XD Backups /XF RestoreThis.cmd /XJD /XO /R:25 /W:15 /MT:32 /V > "%backup_path%\RestoreThis.cmd"
EXIT /B 1

:ExitBatch - Cleanly exit batch processing, regardless how many CALLs
::----------------------------------------------------
if not exist "%temp%\ExitBatchYes.txt" call :buildYes
call :CtrlC <"%temp%\ExitBatchYes.txt" 1>nul 2>&1
:CtrlC
cmd /c exit -1073741510

:buildYes - Establish a Yes file for the language used by the OS
::----------------------------------------------------
pushd "%temp%"
set "yes="
copy nul ExitBatchYes.txt >nul
for /f "delims=(/ tokens=2" %%Y in (
  '"copy /-y nul ExitBatchYes.txt ExitBatchYes.txt
popd
exit /b



:END
::====================================================
ECHO.
ECHO All done!
ECHO.
IF /I "%backup_review%" EQU "1" (
	PAUSE
)
ENDLOCAL
ECHO ON
@EXIT /B 0

The above “source” is a batch file script designed for NT editions of Windows, mainly because it uses RoboCopy to do the heavy lifting. I commented everything, so feel free to dig around as you please… To make this work for you, do the following.

  1. Open Notepad
  2. Copy and Paste the above
  3. Save the file as “BackThisUp.cmd” and put it in the folder you wish to have backups of

Click on the file anytime you want to back that folder up…

 

Final Note: If you haven’t noticed, there is a section of “Predefined” variables, by setting those in the script, you can avoid being prompted to review or fill out everything every time you back your stuff up.

Twitter

Page Hits