Windows Batch Script To Backup Data

As I have briefly mentioned in my previous posts, for my day job I am the primary technical resource for a small business and as a “side gig” I manage web servers for hosting companies. One of the great benefits to this is I have become quite adept at developing command line scripts, or “batch” scripts.

One of the most common, and well suited, applications for a command line script is data backup. Command line scripts can be automated to run at any time without any human interaction and are only limited by… well, nothing.

Why Command Line Scripts?

Having experience with both commercial and free backup programs, I always find command line scripts to be, by far, the most effective tool for the job. Here are a few reasons why:

  • Native Commands: What better way to backup data than by using the functions made available through the program which creates the data. Whether this is the operating system itself via a simple file copy command or a database command to produce a restorable binary file, the source program knows how best to back itself up.
  • Ultimate Control: Since a command line script follows a simple step-by-step procedure, you know exactly what is happening and can easily modify the behavior.
  • Fast: Since everything is a native command, nothing is subject to interpretation. Again, you are using commands provided by the program itself, so overhead is kept to a minimum.
  • Powerful: I have yet to see a backup task which cannot be accomplished through a command line script… and I have done some funky stuff. Albeit, some research and “trial and error” may be required, unless you need something incredibly unique, typically the built in functions and features of the scripting language you are using is more than sufficient.
  • Free and Flexible: Obviously, a command line script does not cost anything (outside the time to develop it), so the emphasis I want to make is command line scripts can be copied to and implemented on other systems and quickly adapted with little to no time or cost. Compare this to the cost of purchasing licenses for backup software on several servers and/or desktop machines.

A Quick Overview Of The Backup Batch Script

Since a lot of people do not have the need/time/desire to learn command line scripting, it is considered somewhat of a “black art”. So to demonstrate the power of the command line, I am providing a simple Windows batch script to backup your important data. This configurable and customizable script does not
require any knowledge (or willingness to learn) of the Windows batch scripting language.

What the backup script does:

  1. Creates full or daily incremental (see below for a definition) backups of files and folders you specify in a separate configuration text file (see below).
    • When a folder is provided, that folder and all sub-folders are backed up.
    • When a file is provided, just that file is backed up.
  2. Compresses (zips) the backed up files. After all files to be backed up are copied, they are compressed to save space. 7-Zip is required to be installed on your system for this to work.
  3. Dates the compressed file and moves it to a storage location. After the backup files are compressed, the resulting archive is given a file name according to the current date and then moved to a configured storage location, such as an external drive or network location.
  4. Cleans up after itself. After all tasks are completed, the batch script cleans up all the temporary files it created.

Requirements:

Windows 2000/XP/2003/Vista,
7-Zip (it’s free).

Configuration file:

The configuration file is simply a text file which contains files and folders to backup, entered one backup item per line. This file must be named “BackupConfig.txt” and be located in the same folder as the backup script. Here is an example of a BackupConfig.txt file (note, the first line is always ignored):

# Enter file and folder names, one per line.
C:\Documents and Settings\Jason Faulkner\Desktop C:\Documents and Settings\Jason Faulkner\My Documents\Important Files C:\Scripts\BackupScript.bat

The example above would backup the Windows user Jason Faulkner’s desktop (and all folders on the desktop), the folder called “Important Files” inside of My Documents (and all folders inside “Important Files”) and the file “BackupScript.bat” inside the C:\Scripts directory.

Types of backups:

  • Full backup: A complete copy of all files and folders (including sub-folders) are included in the backup.
  • Incremental backup: When a folder is provided, only files created or modified on the current date are
    backed up. When a file is provided, it is always backed up, regardless of when it was modified.

The Data Backup Windows Batch Script

I want to emphasize this script is very basic, as all it does is create backups by a utilizing a simple file copy. There are some configuration options you can set:

  • The backup storage location where the resulting compressed backup files are stored.
  • The day of the week the full backup is run (any other day would run an incremental backup).
  • Location of where 7-Zip is installed on your computer. The script is automatically set to look in the default location.

If you have any suggestions or feature requests, please comment below. I would really love to do a follow up article to this post which features an updated script based on reader input.

If you need instructions on how to “use” this script or set up a scheduled task, take a look at the links below the script source.

Without further ado, here it is:
Note: Since the quotes do no display correctly below (and as a result can mess up the script), I have included a plain text link below the script which you can use to get an accurate source to copy from.

@ECHO OFF

REM BackupScript
REM Version 1.01, Updated: 2008-05-21
REM By Jason Faulkner (articles[-at-]132solutions.com)

REM Performs full or incremental backups of folders and files configured by the user.

REM Usage---
REM   > BackupScript

SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION

REM ---Configuration Options---

REM Folder location where you want to store the resulting backup archive.
REM This folder must exist. Do not put a '\' on the end, this will be added automatically.
REM You can enter a local path, an external drive letter (ex. F:) or a network location (ex. \\server\backups)
SET BackupStorage=C:\Backup

REM Which day of the week do you want to perform a full backup on?
REM Enter one of the following: Sun, Mon, Tue, Wed, Thu, Fri, Sat, *
REM Any day of the week other than the one specified below will run an incremental backup.
REM If you enter '*', a full backup will be run every time.
SET FullBackupDay=*

REM Location where 7-Zip is installed on your computer.
REM The default is in a folder, '7-Zip' in your Program Files directory.
SET InstallLocationOf7Zip=%ProgramFiles%\7-Zip

REM +-----------------------------------------------------------------------+
REM | Do not change anything below here unless you know what you are doing. |
REM +-----------------------------------------------------------------------+

REM Usage variables.
SET exe7Zip=%InstallLocationOf7Zip%\7z.exe
SET dirTempBackup=%TEMP%\backup
SET filBackupConfig=BackupConfig.txt

REM Validation.
IF NOT EXIST %filBackupConfig% (
  ECHO No configuration file found, missing: %filBackupConfig%
  GOTO End
)
IF NOT EXIST "%exe7Zip%" (
  ECHO 7-Zip is not installed in the location: %dir7Zip%
  ECHO Please update the directory where 7-Zip is installed.
  GOTO End
)

REM Backup variables.
FOR /f "tokens=1,2,3,4 delims=/ " %%a IN ('date /t') DO (
  SET DayOfWeek=%%a
  SET NowDate=%%d-%%b-%%c
  SET FileDate=%%b-%%c-%%d
)

IF {%FullBackupDay%}=={*} SET FullBackupDay=%DayOfWeek%
IF /i {%FullBackupDay%}=={%DayOfWeek%} (
  SET txtBackup=Full
  SET swXCopy=/e
) ELSE (
  SET txtBackup=Incremental
  SET swXCopy=/s /d:%FileDate%
)

ECHO Starting to copy files.
IF NOT EXIST "%dirTempBackup%" MKDIR "%dirTempBackup%"
FOR /f "skip=1 tokens=*" %%A IN (%filBackupConfig%) DO (
  SET Current=%%~A
  IF NOT EXIST "!Current!" (
    ECHO ERROR! Not found: !Current!
  ) ELSE (
    ECHO Copying: !Current!
    SET Destination=%dirTempBackup%\!Current:~0,1!%%~pnxA
    REM Determine if the entry is a file or directory.
    IF "%%~xA"=="" (
      REM Directory.
      XCOPY "!Current!" "!Destination!" /v /c /i /g /h /q /r /y %swXCopy%
    ) ELSE (
      REM File.
      COPY /v /y "!Current!" "!Destination!"
    )
  )
)
ECHO Done copying files.
ECHO.

SET BackupFileDestination=%BackupStorage%\Backup_%FileDate%_%txtBackup%.zip

REM If the backup file exists, remove it in favor of the new file.
IF EXIST "%BackupFileDestination%" DEL /f /q "%BackupFileDestination%"

ECHO Compressing backed up files. (New window)
REM Compress files using 7-Zip in a lower priority process.
START "Compressing Backup. DO NOT CLOSE" /belownormal /wait "%exe7Zip%" a -tzip -r -mx5 "%BackupFileDestination%" "%dirTempBackup%\"
ECHO Done compressing backed up files.
ECHO.

ECHO Cleaning up.
IF EXIST "%dirTempBackup%" RMDIR /s /q "%dirTempBackup%"
ECHO.

:End
ECHO Finished.
ECHO.

ENDLOCAL

Plain text source is available here: Jason Faulkner’s Backup Script

If you need help getting started with implementing this script, here are a couple of links to help you out:

This is the same script I use to backup my computer daily (with a couple of modifications of course), so I know it works very well. I hope you find it useful.

Enjoy.

Free eBook!

Like what you read?

If so, please join over 28,000 people who receive our exclusive weekly newsletter and computer tips, and get FREE COPIES of 5 eBooks we created, as our gift to you for subscribing. Just enter your name and email below:

Post A Comment Using Facebook

  • mkh

    Okay, can somebody help with this script ?

    when adding single files to the config file nothing happens, i ALLWAYS get an error, using dirs is no problem…

  • mkh

    well, my date /t result is 09-10-2008

    So what would I do about the ” weekdays ” ? :)

    :(

  • http://lichter.nl Willem Mol

    This is getting better and better.
    I want to add one more feature.
    Does anyone know where i can find info on sniffing whether a back-up location (usb hdd) is available?

  • Jason Faulkner

    Use:

    IF EXIST “H:” (enter what to do)
    IF EXIST “I:” (enter what to do)

  • http://www.wisemen.net Ram

    I would like to modify this script to MOVE the files rather copy. i want to use it as an archive script. Will this work?

    • Jason Faulkner

      It *should*, but I haven’t tested it.
      Off the top of my head, I’m not sure how MOVE works with directories.

  • Pingback: Save Your Backups To A Flash Drive | PCMech

  • Tim

    There is a problem with the COPY part – if the destination dir structure has not already been created, COPY will fail.

    So: how do we extract the destination dir from !Destination! to test if it exists?

  • Steve

    Hi I’m getting the following error when doing an incremental
    Invalid parameter – /d:12-04-

    I assume it is coming from the line
    SET swXCopy=/s /d:%FileDate%
    I’m running windows 2003

    • Steve

      Ok I realised that the “date /t” command in win xp and w2k3 (not sure of others) only gives yyyy/mm/dd and NOT the day of the week. So I modified the script with a clever bit of code I found on the web that uses abit of vb to get the day of week.

      Here it is. (Replace Lines 51 to 56)
      I hope the formatting is preserved when I post if not you’r gonna have to work it out

      REM Added to get the Day of Week
      SET “TM_=%TEMP%\_TMP$.VBS”
      >%TM_% ECHO/WSCRIPT.ECHO WEEKDAYNAME(WEEKDAY(DATE),TRUE)
      FOR /F %%? IN (‘CSCRIPT //NOLOGO %TM_%’) DO (SET “DayOfWeek=%%?” &&(DEL %TM_%))
      REM Untidy but remeber that the day of week variable has just been defined above as %DayOfWeek%
      REM Backup variables.
      FOR /f “tokens=1,2,3 delims=/ ” %%a IN (‘date /t’) DO (
      rem SET DayOfWeek=%%a
      SET NowDate=%%c-%%b-%%a
      SET FileDate=%%b-%%c-%%a
      )

      THEN after line 108 I added this to remove files older than 7 days

      forfiles /p %BackupStorage% /s /m *.* /d -7 /c “cmd /c del @path”

      HEY no dodgy comments, it works ok!! There is probably a better way but ….
      Man this would have been SOOO MUCH EASIER if this was a linux box. AAARRGGH Windoz sucks…

  • Ryan

    I like this script. I’m using to backup all my games save files since it’s always a pain to hunt through the filesystem trying to find them.

    I would like to know how I would ‘restore’ the backups using this. I’m not very good with DOS scripting (more of a Linux guy). Maybe add a /restore flag to the script to restore everything? But I have no idea how to do that…

    Someone help?

  • Jason Faulkner

    All the backed up files are compressed to a Zip file and stored in the location you specified (the “BackupStorage” value).
    Just open the Zip file and copy the files you want to restore to the original location.

  • Marco

    Is it possible to find out for the batch script if it needs a full backup, the first one must be a full backup and the rest a incremental? And it ain’t working here at all, I made 1 full backup and then incremental, if I open the zip file it hasn’t made a backup (incremental). It’s empty just some folders and he makes a folder BackUpTemp in my zip file.

    I just did copy/paste and edited the .txt file and .bat for destination.

    Maybe can you help me remote? I have alot of wishes maybe it’s easier to have an expert for 5minutes.

    Best regards,

    Marco

  • Tester

    I tend to clean up before i backup. This way unimportant files are not copied, which saves some time and bytes.

    I use two methods:

    * ccleaner (freeware): there is some need to configure all options well, otherwise useful cookies and program settings will be deleted over and over.
    Command: “%programfiles%\ccleaner\ccleaner.exe” /auto

    * Windows disk cleaner: you can set the desired options via /sageset:x and run disk cleaner with the saved settings using /sagerun:x (x is a number, i use 100)
    Command: cleanmgr /sagerun:x

  • RandyJ

    Looks like a nice little utility!

    Every time I run it I get an empty zip file and I do have a path set in config file.

    My path reads
    E:\download

    There are multiple files and sub directories in that folder

    Thanks in advance
    Randy

    • Jason Faulkner

      If you are getting an empty zip file, it sounds like the script isn’t picking up any files to backup. How long does it take the script to run? If under 5 seconds, most likely you do not have your backup locations configured correctly.

  • TonyC

    Hi Jason, thanks for the script and the tip for KLS which I use as a secondary backup once a week for Outlook.

    One small irritation, when the script runs I get prompted to confirm whether the PST file destination is a File or a Folder ? Does the script not handle that ?

    Res
    Tony

    • Jason Faulkner

      Make sure Outlook isn’t open when you run the script. I believe the file is locked when Outlook is open.

      • TonyC

        Hi Jason, no Outlook isn’t open, to get the script to run unattended I added the following line before the COPY statement (in the FILE branch of the IF statement):

        SET Destination=%dirTempBackup%\!Current:~0,1!%%~pA

        this means that destination will always resolve to a drive\path\ rather than a drive\path\filename\extension, which I believe is what you intended. In fact the DIRECTORY branch may work with this syntax also as I am not sure why you use %%~pnxA here.

        I also used XCOPY as COPY did not work with the modified line above.

        Tony

        PS The only remaining issue I have is that certain files are not copied …I assume because of long file name issue. Does XXCOPY get round this or just flag the files that are not copied as another poster has suggested ?

        • Jason Faulkner

          You shouldn’t need to modify the script to copy a single file, rather just add the full path of the single file as an entry in the config file. I tested this thoroughly before posting the script. Also see my comment above about using COPY vs. XCOPY for single files.

  • mike

    Thanks for the script.
    I do have a couple of questions
    How would I set the options like I do in the 7-zip gui to use the 7z format at a compression level of ultra, a dictionary size of 64 MB, a word size of 273, and a solid block size of 64 GB with 2 CPU threads. In testing what I am backing up this gives the smallest size.
    I would also like to delete the archive after it is 180 days old. This gives me a automated daily backup for six months of my important and daily changing data.
    Thanks again,
    Mike

    • Jason Faulkner

      You can modify the compression format and level by changing the text on the line which does the compression from:
      [...] -tzip -r -mx5 [...]
      to
      [...] -t7z -r -mx9 [...]

      You also need to change the backup file name line to reflect you are using 7z format:
      SET BackupFileDestination=[...].zip
      to
      SET BackupFileDestination=[...].7z

      As for keeping the number of files, there are many things you can do such as “folder rolling” or modify the script to include tools which delete items based on file dates. These are a bit beyond the scope of what this particular script does… maybe if I do a follow-up I will include something like this.

  • TonyC

    Jason, I hear what you are saying, but my config file does contain the full path i.e. drive\folder\filename\extension of any files I am copying wrapped in quotes and I still get the prompt for file or folder.

    As an example, pasted from the current file:

    “C:\Documents and Settings\TonyC\Local Settings\Application Data\Microsoft\Outlook\Outlook.pst”

    Tony

    • Jason Faulkner

      Remove the quotes from the entry in your config file and also use the unmodified script above. I just tested using a single file and it works as expected.

  • TonyC

    Jason it still does not work for me, is there an environment variable that needs adjutsing possibly ?

    Tony

    Btw Surely the quotes are a good idea where there are spaces in the path name ?

  • TonyC

    Jason logically resolving DESTINATION to something that looks like a file and doesnt already exist as a folder is always going to get the DOS prompt for ‘File or Folder’.

    Also using this statement:

    IF “%%~xA”==”” (

    to determine whether you are copying a file or folder is prone to error as in XP a folder can legitimately be called:

    C:\temp\ThisIsAFolder.foo

    Tony

  • Chris

    Hi Jason,

    Great script, thanks for sharing.
    I would like to know if it’s at all possible to make the Destination file not have the same folder structure as the Current. i.e If I’m coping files from a network share for example, the file that gets created includes the whole path of the network share which I’d ideally like to drop.

    What is this line, and particularly the switches doing exactly: SET Destination=%dirTempBackup%\!Current:~0,1!%%~pnxA

    Is that changeable at all to achieve what I’m after?

    Cheers,
    Chris

  • TonyC

    Chris, that line stores your files in a temp directory under your local profile….from there the files are compressed and set to the final destination folder (defined by %BackupStorage%)

    To send the compressed files and folders to the backup directory excluding the path use:

    SET Destination=%dirTempBackup%\%%~nxA

    This will effectively flatten out your directory structure so every file or folder shows under the backup directory. (I think there is a switch that will accomplish the same thing – if I find it, I’ll post it.)

    %%~A is the variable that stores the entry in Backupconfig.txt. It is then That varaible is then used to carry out the copy on. You can modify this variable to send to a different drive/path/location as follows:

    %%~pA – expands %%A to a path only
    %%~nA – expands %%A to a file name only
    %%~xA – expands %%A to a file extension only

    You can combine these to obtain combinations that suit your need. For a fuller explanation go to a Command window and type HELP FOR…Some way down you will find a list of modifiers.

    You may also find these sites useful.

    http://www.robvanderwoude.com/index.html
    http://www.ss64.com/index.html

    Hope that helps in Jason’s absence.

    Tony

    • Chris

      Tony,

      Thanks for the info. Works a treat.

      Cheers,
      Chris

  • TonyC

    Btw:

    Current:~0,1 takes the 1st character of the string representing your file or folder name, e.g.

    C:\SomeFile.txt

    starting at position 0. So in this case it gives:

    C

    So in Jason’s script the drive is converted to a directory in the backup location e.g.

    E:Backups\C\SomeFile.txt

    Tony

  • Anuroop

    Hi,

    I wanted to use this script to copy a file but whenever i run the script, it is not copying the file.

    But when i try to put in the folder name in the config file it works fine, but not for the file.

    Can you please let me know is there any thing to be done.

  • Kevin

    two questions:
    1) what if i only want the full backup to occur once and month and incremental backups every other time?

    2) is it possible to make it so that, instead of the incremental creating a separate file from the full backup, it adds the new files to the full backup file? that way i only have one file per backup period.

    thanks

    • Jason Faulkner

      Kevin,

      You could accomplish #1 by adding this below the line which reads ‘SET DayOfWeek=%%a’:
      SET DayOfMonth=%%c
      and then replace the line reading ‘IF /i {%FullBackupDay%}=={%DayOfWeek%}’ with this:
      IF {%DayOfMonth%}=={01}

      If you are looking to do #2, one of my other tips might be more applicable to you:
      http://www.pcmech.com/article/easily-maintain-a-mirrored-directory-structure/
      The script could be modified to handle this situation, but it is would require more writeup than a reply here.

  • Misty

    This is exactly what I was looking for ;-) Thank you

    Quick question: Is there anyway to make a log of sharing violations (or other errors)?

    • Jason Faulkner

      Misty,

      You can try redirecting the copy lines to a file by adding:
      > C:\LogFile.txt
      to the end of each respective command.
      This is a quick way to accomplish this.

      • Misty

        I tried that, but for some reason the output of these “shared violations” of xcopy is still displayed on the screen and not in the log file. But thank you for the quick replay!

  • Mike

    Hi,

    I have problems with accessing files which consist of two words, e.g. Peter Smith.mdb. The same way I have problems with two words directories. Any solution? (XP)

    Thanks!

    Copy c:\Peter Smith.mdb e:\New Backup\Peter Smith.mdb

    • http://www.menga.net Rich Menga

      Put quotes around it, ex:

      “c:\Peter Smith.mdb” “e:\New Backup\Peter Smith.mdb”

      • Mike

        Thank you! :o D

What’s Your Preference?

Daily Alerts

Each day we send out a quick email to thousands of PCMECH readers to notify them of new posts. This email is just a short, plain email with titles and links to our latest posts. You can unsubscribe from this service at any time.

You can subscribe to it by leaving your email address in the following field and confirming your subscription when you get an email asking you to do so.

Enter your email address for
Daily Updates:

Weekly Newsletter

Running for over 6 years, the PCMECH weekly newsletter helps you keep tabs on the world of tech. Each issue includes news bits, an article, an exclusive rant as well as a download of the week. This newsletter is subscribed to by over 28,000 readers (many who also subscribe to the other option) - come join the community!

To subscribe to this weekly newsletter simply add your email address to the following field and then follow the confirmation prompts. You will be able to unsubscribe at any time.

Enter your email address for
Free Weekly Newsletter: