D
dderkits
Below is a new version of the backup script that I posted to USENET on
5 July 2005 (initial version) and 9 Sept 2006 (revised version). This
new version can also be found at:
http://www.derkits.com/apps/serverbackup.txt
(be sure to change the file attribute to .cmd before using it)
The version below may be affected by line wrapping. So, it is
probably best to download the script from the above URI.
The main improvements are:
- Inserted code after the backup operations and before the robocopy
operation to parse the ntbackup logs for certain error messages that
will indicate a problem even if ntbackup returns a "success"
errorlevel.
- Under Exchange backup section, corrected position of line "set
saveerrorlevel=%errorlevel%".
This is still a caveat:
- Robocopy, when run in a batch script, can have problems with very
large backup (.bkf) files. I have noticed this with individual .bkf
files that are around/over 110GB in size, and it is more likely to
occur on servers that have the /3GB switch enabled in boot.ini. In
some cases, rebooting the server will resolve the problem, at least
termporarily. One workaround is to copy the file manually, using
robocopy or another method. But, if you are encountering this error
often, then your infrastructure may have outgrown the capabilities of
this script. For additional information on this robocopy "bug",
search
the web for: robocopy insufficient resources. See also:
http://support.microsoft.com/default.aspx?scid=kben-usQ259837
Some text from my earlier post is still relevant, so I'll repeat it
here.
"Below is a batch-based script that I have developed for a few
clients
in setting them up with disk-based backup (using USB2 and/or FireWire
external hard drives, such as those available from AcomData and
others). I'm posting it here in case anyone has a use for it.
This material is supplied without any warranty or support. You
should
periodically test the quality of your backups no matter what backup
software you use, including running test restores on test hardware.
Although this backup script should be usable "out-of-the-box", it is
best if the sysadmin reviews it and makes an effort to understand it,
before actually using it. This is freely-available (no copyright)
and
may be copied/customized/used as desired.
Reasons to consider a disk-based backup approach:
- Disk backup is usually considerably less expensive than tape
backup,
once all of the hardware and software are factored in. This is
certainly true at larger data sizes, which is sometimes the
case for file servers and/or email servers.
- Disk backup is usually faster than tape backup, and easier to
restore
from.
- Disk drives are usually more portable than tape drives, and they
have
strong OS support (with the drivers preloaded in most cases).
- This backup script is free, and it leverages the capabilities of
ntbackup, which comes with Windows for no additional cost.
- Disk backup can be easily scheduled using Scheduled Tasks.
- Off-site capabilities are easily supported, by having one external
drive always attached to hold the backups, and then another drive (or
set of drives) that mirror the content of the always-attached drive
and
that rotate a few times per week - e.g. at any given moment, one
rotated drive is attached, one is in transit, and one is safely
off-site). See the script for additional details about this
mechanism.
Granted, this backup script is a batch file, but for relatively
simple
purposes a batch is okay (using cmd, not bat, of course). If I were
doing this formally, I'd probably write it in vbscript, but batch is
somewhat more accessible to the Windows community.
Feel free to email me if you find any bugs or have any comments.
Enjoy,
- David Derkits
http://www.derkits.com/
@echo off
echo Version 2.50 (25Aug07) - David Derkits
(dderkits@alumni.caltech.edu)
echo Runs a backup to two external hard drives and logs progress and
errors
echo into an email.
echo This script can be executed manually but, in practice, is usually
run
echo automatically using Scheduled Tasks.
echo This script must be run locally on the server that is to be
backed-up.
echo.
echo Command syntax:
echo.
echo serverbackup.cmd weeknum baktype
echo.
echo where weeknum is: 1, 2, or 3 (assuming a three-week rotation
this
echo script supports, without modification, rotations of longer or
echo shorter duration). Generally, weeknum is: 1, 2, 3, ..., n
echo Note that weeknum can generally be thought of as a "rotation
number"
echo it does not necessarily have to align on a weekly repetition.
echo.
echo where baktype is: normal or diff
echo.
echo example:
echo backupscript 1 diff
echo.
echo Changelog:
echo 8/25/07: Created version 2.50. Inserted code after the backup
echo operations and before the robocopy operation to parse the
ntbackup
echo logs for certain error messages that will indicate a problem even
echo if ntbackup returns a "success" errorlevel. Under Exchange
backup
echo section, corrected position of line "set saveerrorlevel=
%errorlevel%".
rem -----
rem THIS FILE IS MADE AVAILABLE WITHOUT ANY WARRANTY OR SUPPORT. You
must
rem periodically test the quality of your backups no matter what
backup
rem software you use, including running test restores on test
hardware.
rem Although this backup script should be usable "out-of-the-box", it
is
rem best if the sysadmin reviews it and makes an effort to understand
it,
rem before actually using it. This is freely-available (no copyright)
and
rem may be copied/customized/used as desired.
rem -----
rem -----
rem BEFORE USING THIS SCRIPT FOR THE FIRST TIME
rem 1) Edit the Script Customizations (next section, below).
rem 2) Attach two external hard drives such that they are assigned
drive
rem letters by the Windows OS. Format these drives using NTFS.
rem 1) Designate one drive as the Fixed Drive, and create a file at
the
rem root of the drive that has a filename matching that shown in
the
rem Script Customizations section below.
rem 2) Designate the second drive as the Rotated Drive, and create
a file
rem at the root of the drive that has a filename matching that
shown
rem in the Script customizations section below.
rem 3) In most cases, there will be more than one Rotated Drive, so
that
rem one drive is connected, one is in transit, and one is off-
site.
rem Follow the above step for each such Rotated Drive.
rem 2) If the script will be used to back-up Exchange data, then
rem create the exchange.bks file locally as follows:
rem 1) Open Windows Backup (Start button -> All Programs ->
Accessories ->
rem System Tools -> Backup.
rem 2) If Backup launches in "Backup or Restore Wizard" mode, then
uncheck
rem "Always start in wizard mode", click Next, click Next, click
Cancel,
rem and relaunch Backup.
rem 3) In the "Backup Utility" window, go to the "Backup" tab.
Find the
rem "Microsoft Exchange Server" section and expand it you see
the
rem "Microsoft Information Store" entry. Checkmark the checkbox
rem next to this entry.
rem 4) Go to menu bar Job -> Save Selections As..., and save the
file as:
rem c:\active\scripts\serverbackup\exchange.bks
rem (or whatever file/path that is entered in the Script
Customizations
rem section below)
rem 5) Close Windows Backup. The file is now created.
rem NOTE: The exchange.bks file will have to be manually recreated
whenever
rem an Exchange Storage Group is added or deleted (so that the
rem exchange.bks file is aware of the change).
rem 3) Create the Alert Group (ga.*) in the Active Directory
rem (see the "emailaddress" variable below for the name format).
rem Example: ga.servername.backup-notify
rem (This step can be skipped if the email address to which backup
rem reports will be sent already exists.)
rem 4) Modify the Registry so that only one backup log (rather than
rem 10 logs, rotated) is used. To do this, load the registry file
rem ntbackup-onlyonelog.reg (which is usually located in the same
folder as
rem serverbackup.cmd) under the user account that ntbackup will
rem impersonate when conducting its backups.
rem For reference, this is the content of the .reg file (note: two
lines):
rem [HKEY_CURRENT_USER\Software\Microsoft\Ntbackup\Log Files]
rem "Log File Count"=dword:00000001
rem 5) Set up the Scheduled Tasks if Scheduled Tasks are to be used.
rem For each week (or "rotation"), there are normally two Scheduled
Tasks:
rem (assuming a three-week rotation and a 12am start time note
that a
rem three-week rotation would require a total of six Scheduled
Tasks)
rem "Backup Week 1 Normal"
rem Run: c:\active\scripts\serverbackup\serverbackup.cmd 1
normal
rem Schedule: Weekly, every 3 weeks, at 12am on Monday
rem "Backup Week 1 Diff"
rem Run: c:\active\scripts\serverbackup\serverbackup.cmd 1
diff
rem Schedule: Weekly, every 3 weeks, at 12am on Tues, Weds,
Thurs,
rem Fri, and Sat
rem For both:
rem Run as: DOMAINNAMEHERE\Administrator
rem Enabled
rem Rest of the settings = use the defaults
rem The backup script can handle any Scheduled Task configuration,
so the
rem above is just one example of many possible tasks.
rem -----
rem SCRIPT CUSTOMIZATIONS
rem 1) Specify the server to be backed-up
rem
set srvname=servername
rem 2) Specify the names of the files to be placed at the root of the
external
rem backup drives to indicate their eligibility as backup drives:
rem (this is crucial in preventing accidential erasure of data)
rem
set fixedfilename=autobackup-fixed-ok.txt
rem
set rotatedfilename=autobackup-rotated-ok.txt
rem 3a) Specify whether the server needs an Exchange backup:
rem use "true" or "false" (w/o quotes)
rem
set bakexchange=false
rem
rem 3b) If an Exchange backup is specified, on the server in question,
ensure
rem that the exchange.bks file exists, and specify its path:
rem
set exchangebksfile=c:\active\scripts\serverbackup\exchange.bks
rem 4a) Specify whether the server needs to backup a file on another
rem server:
rem use "true" or "false" (w/o quotes)
rem
set bakother=false
rem
rem 4b) If this is the case, then specify the location of the file,
using its
rem full file name and its UNC path:
rem
set otherfile=\\otherservername\c$\backup\otherserver-drivec-
sysstate.bkf
rem
rem 4c) Specify a friendly name for this backup:
rem
set bakothername=otherserver-drivec-sysstate
rem
rem Note: A backup of a file on another server will only be done
during
rem a backup of type normal (i.e. baktype=normal). Be sure that the
user
rem account under which serverbackup.cmd runs has the right to access
rem the other location.
rem 5) Specify the email address that will be used in the From: and
To:
rem fields of the emailed backup report:
rem Example: ga.%srvname%.backup-notify@company.com
rem
set emailaddress=ga.%srvname%.backup-notify@company.com
rem 6) Specify the Exchange email pickup folder. The user account
under
rem which serverbackup.cmd runs must have write access to this
location.
rem For authentication purposes, this location should be in the
same
rem Windows domain as the server on which the backup script is
running.
rem
set exchpickup=\\mailservername\c$\Program Files\Exchsrvr\Mailroot\vsi
1\PickUp
rem -----
rem Note: Carets are used to wrap lines that extend beyond 80
characters.
rem Note: The line "cmd /c exit /b 5" is used to set the errorlevel to
a
rem non-zero value so that we know that the next command
executed
rem at least to the point that a new errorlevel was set.
set weeknum=%1
set baktype=%2
set baktypeabbrev=%baktype%
if /i %baktype%==diff set baktype=differential
set baklog=%temp%\backuplog.log
set robolog=%temp%\robocopylog.log
set emailtop=%temp%\emailtop.txt
set ntbackuplog=%userprofile%\Local Settings\Application ^
Data\Microsoft\Windows NT\NTBackup\data\backup01.log
set ntbackupall=%temp%\ntbackupall.log
rem Delete any pre-existing log files:
del "%baklog%"
del "%ntbackuplog%"
del "%robolog%"
del "%emailtop%"
del "%ntbackupall%"
rem Write the header of the baklog:
echo Starting Server Backup> "%baklog%"
echo.>> "%baklog%"
echo Server, Backup Details, and start Date/Time:>> "%baklog%"
echo %srvname%, Week %weeknum%, Type %baktype%>> "%baklog%"
date /t>> "%baklog%"
time /t>> "%baklog%"
echo.>> "%baklog%"
rem Make sure the script is being run on the correct server
if /i %srvname%==%computername% goto proper-server
echo This script must be run locally on the server to be ^
backed-up.>> "%baklog%"
echo If this is the correct server, then open this script>>
"%baklog%"
echo in notepad and edit the "srvname" variable (the script>>
"%baklog%"
echo believes the file server is %srvname%).>> "%baklog%"
echo Script aborting.>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=Wrong Server
goto end
roper-server
rem Make sure that weeknum (%1) has been specified
if not [%1]==[] goto weeknum-specified
echo Please include the weeknum (a positive integer) when ^
running the script:>> "%baklog%"
echo serverbackup.cmd weeknum baktype>> "%baklog%"
echo Script aborting.>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=Variable weeknum Not Specified
goto end
:weeknum-specified
rem Make sure that baktype (%2) has been specified properly
if %2==normal goto baktype-specified
if %2==diff goto baktype-specified
echo Please include the proper baktype when running ^
the script:>> "%baklog%"
echo serverbackup.cmd weeknum baktype>> "%baklog%"
echo where baktype is: normal or diff>> "%baklog%"
echo Script aborting.>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=Variable baktype Not Specified
goto end
:baktype-specified
rem Check all locally-attached drives to find the fixed (non-rotated)
rem external backup drive, by looking for its tag. This step will
rem find and use the alphabetically-first such drive, even if multiple
rem such drives are attached.
rem
set fixeddriveletter=none
for %%f in (z y x w v u t s r q p o n m l k j i h g f e d) do if ^
exist %%f:\%fixedfilename% set fixeddriveletter=%%f
if not %fixeddriveletter%==none goto fixeddrive-is-ready
echo The external Fixed Drive is not attached or it is not ^
tagged for>> "%baklog%"
echo use by the backup mechanism (the file %fixedfilename
%>>"%baklog%"
echo must exist at the root of the drive).>> "%baklog%"
echo Please take corrective action.>> "%baklog%"
echo Backup aborting.>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=Failure: Fixed Drive Not Ready
goto end
:fixeddrive-is-ready
echo External Fixed Drive, drive %fixeddriveletter%:, is ready.>>
"%baklog%"
echo.>> "%baklog%"
rem If the type of backup is Normal, delete the pre-existing backup
files
rem since backup type Normal implies we are starting a new week:
if /i %baktype%==normal del /q %fixeddriveletter%:\week%weeknum%\*.*
rem If the type of backup is Differential, then we need to know
whether
rem it is the first, second, etc. Differential backup of the week, so
that
rem we don't overwrite any previous Differential backup files. We do
this
rem by checking for preexisting Differential backup files.
rem Note: If there are more than 49 differential backup files, then
this
rem will not operate properly.
if /i %baktype%==normal goto skip-diff-check
for /L %%f in (50,-1,1) do if not exist ^
%fixeddriveletter%:\week%weeknum%\%srvname%-week%weeknum%-diff%%f-sys^
state.bkf set diffnum=%%f
echo Variable diffnum is %diffnum%.>> "%baklog%"
echo.>> "%baklog%"
set baktypeabbrev=diff%diffnum%
:skip-diff-check
rem Backup files have a labeling scheme, which is of the form:
rem servername-week1-diff3
rem This is used in the file name and in the tape name.
rem We represent this with a new variable:
set bakname=%srvname%-week%weeknum%-%baktypeabbrev%
rem -----
rem Run the backup of the System State:
rem The errorlevel entry will help catch if the backup aborts.
set jobname=sysstate
echo Starting backup of %jobname%.>> "%baklog%"
date /t>> "%baklog%"
time /t>> "%baklog%"
echo.>> "%baklog%"
rem Note: system state is always type=Normal.
rem The ntbackup command is sufficiently long that we first prepare
the
rem command as a variable, then we run ntbackup using this variable as
rem the parameter:
set bakss=backup systemstate /n "%bakname%-%jobname%" /d
set bakss=%bakss% "%bakname%-%jobname%" /v:yes /r:no /rs:no /hcff /m
normal
set bakss=%bakss% /j "%jobname%" /l:s /f
set bakss=%bakss% "%fixeddriveletter%:\week%weeknum%\%bakname%-%jobname
%.bkf"
cmd /c exit /b 5
ntbackup %bakss%
set saveerrorlevel=%errorlevel%
type "%ntbackuplog%"> "%ntbackupall%"
echo.>> "%ntbackupall%"
rem Check the errorlevel and notify admin if there is a problem.
if %saveerrorlevel%==0 goto bak-sysstate-ok
echo Backup of %jobname% failed.>> "%baklog%"
echo Check the backup log for details.>> "%baklog%"
echo Backup aborting.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=Failure: Backup of %jobname% failed
goto end
:bak-sysstate-ok
echo Backup of %jobname% completed successfully.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
echo.>> "%baklog%"
rem -----
rem -----
rem Run the backup of the C Drive:
rem The errorlevel entry will help catch if the backup aborts.
set jobname=drivec
echo Starting backup of %jobname%.>> "%baklog%"
date /t>> "%baklog%"
time /t>> "%baklog%"
echo.>> "%baklog%"
rem The ntbackup command is sufficiently long that we first prepare
the
rem command as a variable, then we run ntbackup using this variable as
rem the parameter:
set bakdc=backup c:\ /n "%bakname%-%jobname%" /d "%bakname%-%jobname%"
set bakdc=%bakdc% /v:yes /r:no /rs:no /hcff /m %baktype% /j "%jobname
%"
set bakdc=%bakdc% /l:s /f
set bakdc=%bakdc% "%fixeddriveletter%:\week%weeknum%\%bakname%-%jobname
%.bkf"
cmd /c exit /b 5
ntbackup %bakdc%
set saveerrorlevel=%errorlevel%
type "%ntbackuplog%">> "%ntbackupall%"
echo.>> "%ntbackupall%"
rem Check the errorlevel and notify admin if there is a problem.
if %saveerrorlevel%==0 goto bak-drivec-ok
echo Backup of %jobname% failed.>> "%baklog%"
echo Check the backup log for details.>> "%baklog%"
echo Backup aborting.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=Failure: Backup of %jobname% failed
goto end
:bak-drivec-ok
echo Backup of %jobname% completed successfully.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
echo.>> "%baklog%"
rem -----
rem -----
rem The next step is to back-up Exchange data, but only if the
rem bakexchange variable is set to true:
if not %bakexchange%==true goto skip-bakexchange
rem Run the backup of the Exchange database:
rem The errorlevel entry will help catch if the backup aborts.
set jobname=exchange
echo Starting backup of %jobname%.>> "%baklog%"
date /t>> "%baklog%"
time /t>> "%baklog%"
echo.>> "%baklog%"
rem The ntbackup command is sufficiently long that we first prepare
the
rem command as a variable, then we run ntbackup using this variable as
rem the parameter:
set bakex=backup "@%exchangebksfile%" /n "%bakname%-%jobname%" /d
set bakex=%bakex% "%bakname%-%jobname%" /v:yes /r:no /rs:no /hcff /m
set bakex=%bakex% %baktype% /j "%jobname%" /l:s /f
set bakex=%bakex% "%fixeddriveletter%:\week%weeknum%\%bakname%-%jobname
%.bkf"
cmd /c exit /b 5
ntbackup %bakex%
set saveerrorlevel=%errorlevel%
type "%ntbackuplog%">> "%ntbackupall%"
echo.>> "%ntbackupall%"
rem Check the errorlevel and notify admin if there is a problem.
if %saveerrorlevel%==0 goto bak-exchange-ok
echo Backup of %jobname% failed.>> "%baklog%"
echo Check the backup log for details.>> "%baklog%"
echo Backup aborting.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=Failure: Backup of %jobname% failed
goto end
:bak-exchange-ok
echo Backup of %jobname% completed successfully.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
echo.>> "%baklog%"
:skip-bakexchange
rem -----
rem -----
rem This next step allows the local server to backup a file
rem on another computer (usually a .bkf file representing a
rem backup generated locally on that other computer), but
rem only if the bakother variable is set to true:
if not %bakother%==true goto skip-bakother
rem This backup will only be done during a normal backup.
if not %baktype%==normal goto skip-bakother
set jobname=%bakothername%
echo Starting backup of %jobname%.>> "%baklog%"
date /t>> "%baklog%"
time /t>> "%baklog%"
echo.>> "%baklog%"
cmd /c exit /b 5
copy "%otherfile%" %fixeddriveletter%:\week%weeknum%
set saveerrorlevel=%errorlevel%
rem Check the errorlevel and notify admin if there is a problem.
if %saveerrorlevel%==0 goto bakother-ok
echo Backup %jobname% failed.>> "%baklog%"
echo Backup aborting.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=Failure: Backup of %jobname% failed
goto end
:bakother-ok
echo Backup of %jobname% completed successfully.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
echo.>> "%baklog%"
:skip-bakother
rem -----
rem Now that all of the backups have completed, let's check the
rem ntbackup logs (which are all contained in the file that is
rem represented by the "ntbackupall" variable) for mention of
rem any errors that - for whatever reason - did not cause
rem ntbackup to generate a formal errorlevel alert.
rem Note: You may manually add additional findstr commands (simply
rem repeat the two-line block and use a different search string). Be
rem sure to test any additions to ensure that they do not detect
valid
rem log entries.
findstr /i /c:"error " "%ntbackupall%"
if not errorlevel 1 goto ntbackuplogerror-failure
findstr /i /c:"error:" "%ntbackupall%"
if not errorlevel 1 goto ntbackuplogerror-failure
findstr /i /c:"The operation did not successfully complete."
"%ntbackupall%"
if not errorlevel 1 goto ntbackuplogerror-failure
findstr /i /c:"Insufficient disk space." "%ntbackupall%"
if not errorlevel 1 goto ntbackuplogerror-failure
goto ntbackuplogerror-success
:ntbackuplogerror-failure
set fatalerror=Failure: ntbackup Error (see "ntbackup log" section)
goto end
:ntbackuplogerror-success
rem Check all locally-attached drives to find the rotated
rem external backup drive, by looking for its tag. This step will
rem find and use the alphabetically-first such drive, even if multiple
rem such drives are attached. This step will double-check that one
rem external drive is not tagged as both the Fixed Drive and the
rem Rotated Drive.
rem
set rotateddriveletter=none
for %%f in (z y x w v u t s r q p o n m l k j i h g f e d) do if ^
exist %%f:\%rotatedfilename% set rotateddriveletter=%%f
if not %rotateddriveletter%==none goto rotateddrive-is-ready
echo The external Rotated Drive is not attached or it is not ^
tagged for>> "%baklog%"
echo use by the backup mechanism (the file %rotatedfilename
%>>"%baklog%"
echo must exist at the root of the drive).>> "%baklog%"
echo Please take corrective action.>> "%baklog%"
echo Backup aborting.>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=Failure: Rotated Drive Not Ready
goto end
if not %rotateddriveletter%==%fixeddriveletter% goto rotateddrive-is-
ready
echo One drive, drive %rotateddriveletter%:, is tagged as both the
^
Fixed Drive>> "%baklog%"
echo and the Rotated Drive. This is not allowed. Please take ^
corrective action>> "%baklog%"
echo (usually by deleting one of the file tags at the root of the
^
drive).>> "%baklog%"
echo Backup aborting.>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=Failure: Rotated Drive is also the Fixed Drive
goto end
:rotateddrive-is-ready
echo External Rotated Drive, drive %rotateddriveletter%:, is ^
ready.>> "%baklog%"
echo.>> "%baklog%"
rem Run the robocopy command.
echo Starting Fixed-to-Rotated Copy Operation.>> "%baklog%"
date /t>> "%baklog%"
time /t>> "%baklog%"
echo.>> "%baklog%"
rem The robocopy command is sufficiently long that we first prepare
the
rem command as a variable, then we run robocopy using this variable as
rem the parameter:
set robocmd=%fixeddriveletter%: %rotateddriveletter%: /mir /xd
set robocmd=%robocmd% %fixeddriveletter%:\RECYCLER
set robocmd=%robocmd% "%fixeddriveletter%:\System Volume Information"
set robocmd=%robocmd% %rotateddriveletter%:\RECYCLER
set robocmd=%robocmd% "%rotateddriveletter%:\System Volume
Information"
set robocmd=%robocmd% /xf %fixeddriveletter%:\%fixedfilename%
set robocmd=%robocmd% %rotateddriveletter%:\%rotatedfilename%
set robocmd=%robocmd% /log:"%robolog%" /tee /np
cmd /c exit /b 100
robocopy %robocmd%
set saveerrorlevel=%errorlevel%
rem Check the errorlevel of the robocopy command and notify admin if
a
rem problem occurred.
rem Errorlevels 0-3 are OK.
if %saveerrorlevel% LEQ 3 goto robocopy-checktwo
goto robocopy-failure
:robocopy-checktwo
if %saveerrorlevel% GEQ 0 goto robocopy-success
:robocopy-failure
echo The copy operation from %fixeddriveletter%: to ^
%rotateddriveletter%: failed.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
echo (Errorlevels 0-3 are OK)>> "%baklog%"
echo Check the logs for details.>> "%baklog%"
echo Backup Aborting>> "%baklog%"
date /t>> "%baklog%"
time /t>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=Failure: Fixed-to-Rotated Copy Operation Failed
goto end
:robocopy-success
echo Fixed-to-Rotated Copy Operation Successful.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
echo (Errorlevels 0-3 are OK)>> "%baklog%"
date /t>> "%baklog%"
time /t>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=Success: Backup Successful
rem If the backup process has gone this far, then it means that
rem both external drives are properly attached. So, at this
rem point (when all priority backup and mirroring operations are
complete),
rem if the type of backup is Normal, then we will run a chkdsk (in
read-only
rem mode) on both external drives to check their status.
rem Write notice of any possible errors to baklog and fatalerror.
if not %baktype%==normal goto skip-chkdsk
echo Starting chkdsk of Fixed drive, drive %fixeddriveletter%:.>>
"%baklog%"
echo.>> "%baklog%"
cmd /c exit /b 5
chkdsk %fixeddriveletter%:
set saveerrorlevel=%errorlevel%
if %saveerrorlevel%==0 goto chk-fixeddrive-okay
echo chkdsk detected possible errors on the Fixed Drive, ^
drive %fixeddriveletter%:.>> "%baklog%"
echo With this drive attached, run chkdsk %fixeddriveletter%: ^
/f /r /x on %srvname%>> "%baklog%"
echo as soon as possible.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
date /t>> "%baklog%"
time /t>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=%fatalerror% but see chkdsk for Fixed Drive
goto skip-chk-fixeddrive-okay
:chk-fixeddrive-okay
echo chkdsk of Fixed drive, drive %fixeddriveletter%:, reported no ^
errors.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
date /t>> "%baklog%"
time /t>> "%baklog%"
echo.>> "%baklog%"
:skip-chk-fixeddrive-okay
echo Starting chkdsk of Rotated drive, drive ^
%rotateddriveletter%:.>> "%baklog%"
echo.>> "%baklog%"
cmd /c exit /b 5
chkdsk %rotateddriveletter%:
set saveerrorlevel=%errorlevel%
if %saveerrorlevel%==0 goto chk-rotateddrive-okay
echo chkdsk detected possible errors on the Rotated Drive, drive ^
%rotateddriveletter%:.>> "%baklog%"
echo With this drive attached, run chkdsk %rotateddriveletter%: ^
/f /r /x on %srvname%>> "%baklog%"
echo as soon as possible.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
date /t>> "%baklog%"
time /t>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=%fatalerror% but see chkdsk for Rotated Drive
goto skip-chk-rotateddrive-okay
:chk-rotateddrive-okay
echo chkdsk of Rotated drive, drive %rotateddriveletter%:, reported no
^
errors.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
date /t>> "%baklog%"
time /t>> "%baklog%"
echo.>> "%baklog%"
:skip-chk-rotateddrive-okay
:skip-chkdsk
:end
rem Build the summary email for the admin and send it using an
Exchange
rem email pickup folder.
echo X-sender: %emailaddress%> "%emailtop%"
echo x-receiver: %emailaddress%>> "%emailtop%"
echo From: %emailaddress%>> "%emailtop%"
echo To: %emailaddress%>> "%emailtop%"
echo Subject: Backup of %srvname%: %fatalerror%>> "%emailtop%"
echo.>> "%emailtop%"
echo Server Backup Report for %srvname%>> "%emailtop%"
echo Status message is: %fatalerror%>> "%emailtop%"
echo.>> "%emailtop%"
echo --------------- start backup script log -------------->>
"%emailtop%"
echo.>> "%emailtop%"
type "%baklog%">> "%emailtop%"
echo.>> "%emailtop%"
echo ----------------- start ntbackup log ----------------->>
"%emailtop%"
echo.>> "%emailtop%"
type "%ntbackupall%">> "%emailtop%"
echo.>> "%emailtop%"
echo ----------------- start robocopy log ----------------->>
"%emailtop%"
echo.>> "%emailtop%"
type "%robolog%">> "%emailtop%"
echo.>> "%emailtop%"
echo ---------------- end of Backup Report ---------------->>
"%emailtop%"
echo.>> "%emailtop%"
copy "%emailtop%" "%exchpickup%"
rem Delete the log files
del "%baklog%"
del "%ntbackuplog%"
del "%robolog%"
del "%emailtop%"
del "%ntbackupall%"
rem End of Backup Script
5 July 2005 (initial version) and 9 Sept 2006 (revised version). This
new version can also be found at:
http://www.derkits.com/apps/serverbackup.txt
(be sure to change the file attribute to .cmd before using it)
The version below may be affected by line wrapping. So, it is
probably best to download the script from the above URI.
The main improvements are:
- Inserted code after the backup operations and before the robocopy
operation to parse the ntbackup logs for certain error messages that
will indicate a problem even if ntbackup returns a "success"
errorlevel.
- Under Exchange backup section, corrected position of line "set
saveerrorlevel=%errorlevel%".
This is still a caveat:
- Robocopy, when run in a batch script, can have problems with very
large backup (.bkf) files. I have noticed this with individual .bkf
files that are around/over 110GB in size, and it is more likely to
occur on servers that have the /3GB switch enabled in boot.ini. In
some cases, rebooting the server will resolve the problem, at least
termporarily. One workaround is to copy the file manually, using
robocopy or another method. But, if you are encountering this error
often, then your infrastructure may have outgrown the capabilities of
this script. For additional information on this robocopy "bug",
search
the web for: robocopy insufficient resources. See also:
http://support.microsoft.com/default.aspx?scid=kben-usQ259837
Some text from my earlier post is still relevant, so I'll repeat it
here.
"Below is a batch-based script that I have developed for a few
clients
in setting them up with disk-based backup (using USB2 and/or FireWire
external hard drives, such as those available from AcomData and
others). I'm posting it here in case anyone has a use for it.
This material is supplied without any warranty or support. You
should
periodically test the quality of your backups no matter what backup
software you use, including running test restores on test hardware.
Although this backup script should be usable "out-of-the-box", it is
best if the sysadmin reviews it and makes an effort to understand it,
before actually using it. This is freely-available (no copyright)
and
may be copied/customized/used as desired.
Reasons to consider a disk-based backup approach:
- Disk backup is usually considerably less expensive than tape
backup,
once all of the hardware and software are factored in. This is
certainly true at larger data sizes, which is sometimes the
case for file servers and/or email servers.
- Disk backup is usually faster than tape backup, and easier to
restore
from.
- Disk drives are usually more portable than tape drives, and they
have
strong OS support (with the drivers preloaded in most cases).
- This backup script is free, and it leverages the capabilities of
ntbackup, which comes with Windows for no additional cost.
- Disk backup can be easily scheduled using Scheduled Tasks.
- Off-site capabilities are easily supported, by having one external
drive always attached to hold the backups, and then another drive (or
set of drives) that mirror the content of the always-attached drive
and
that rotate a few times per week - e.g. at any given moment, one
rotated drive is attached, one is in transit, and one is safely
off-site). See the script for additional details about this
mechanism.
Granted, this backup script is a batch file, but for relatively
simple
purposes a batch is okay (using cmd, not bat, of course). If I were
doing this formally, I'd probably write it in vbscript, but batch is
somewhat more accessible to the Windows community.
Feel free to email me if you find any bugs or have any comments.
Enjoy,
- David Derkits
http://www.derkits.com/
@echo off
echo Version 2.50 (25Aug07) - David Derkits
(dderkits@alumni.caltech.edu)
echo Runs a backup to two external hard drives and logs progress and
errors
echo into an email.
echo This script can be executed manually but, in practice, is usually
run
echo automatically using Scheduled Tasks.
echo This script must be run locally on the server that is to be
backed-up.
echo.
echo Command syntax:
echo.
echo serverbackup.cmd weeknum baktype
echo.
echo where weeknum is: 1, 2, or 3 (assuming a three-week rotation
this
echo script supports, without modification, rotations of longer or
echo shorter duration). Generally, weeknum is: 1, 2, 3, ..., n
echo Note that weeknum can generally be thought of as a "rotation
number"
echo it does not necessarily have to align on a weekly repetition.
echo.
echo where baktype is: normal or diff
echo.
echo example:
echo backupscript 1 diff
echo.
echo Changelog:
echo 8/25/07: Created version 2.50. Inserted code after the backup
echo operations and before the robocopy operation to parse the
ntbackup
echo logs for certain error messages that will indicate a problem even
echo if ntbackup returns a "success" errorlevel. Under Exchange
backup
echo section, corrected position of line "set saveerrorlevel=
%errorlevel%".
rem -----
rem THIS FILE IS MADE AVAILABLE WITHOUT ANY WARRANTY OR SUPPORT. You
must
rem periodically test the quality of your backups no matter what
backup
rem software you use, including running test restores on test
hardware.
rem Although this backup script should be usable "out-of-the-box", it
is
rem best if the sysadmin reviews it and makes an effort to understand
it,
rem before actually using it. This is freely-available (no copyright)
and
rem may be copied/customized/used as desired.
rem -----
rem -----
rem BEFORE USING THIS SCRIPT FOR THE FIRST TIME
rem 1) Edit the Script Customizations (next section, below).
rem 2) Attach two external hard drives such that they are assigned
drive
rem letters by the Windows OS. Format these drives using NTFS.
rem 1) Designate one drive as the Fixed Drive, and create a file at
the
rem root of the drive that has a filename matching that shown in
the
rem Script Customizations section below.
rem 2) Designate the second drive as the Rotated Drive, and create
a file
rem at the root of the drive that has a filename matching that
shown
rem in the Script customizations section below.
rem 3) In most cases, there will be more than one Rotated Drive, so
that
rem one drive is connected, one is in transit, and one is off-
site.
rem Follow the above step for each such Rotated Drive.
rem 2) If the script will be used to back-up Exchange data, then
rem create the exchange.bks file locally as follows:
rem 1) Open Windows Backup (Start button -> All Programs ->
Accessories ->
rem System Tools -> Backup.
rem 2) If Backup launches in "Backup or Restore Wizard" mode, then
uncheck
rem "Always start in wizard mode", click Next, click Next, click
Cancel,
rem and relaunch Backup.
rem 3) In the "Backup Utility" window, go to the "Backup" tab.
Find the
rem "Microsoft Exchange Server" section and expand it you see
the
rem "Microsoft Information Store" entry. Checkmark the checkbox
rem next to this entry.
rem 4) Go to menu bar Job -> Save Selections As..., and save the
file as:
rem c:\active\scripts\serverbackup\exchange.bks
rem (or whatever file/path that is entered in the Script
Customizations
rem section below)
rem 5) Close Windows Backup. The file is now created.
rem NOTE: The exchange.bks file will have to be manually recreated
whenever
rem an Exchange Storage Group is added or deleted (so that the
rem exchange.bks file is aware of the change).
rem 3) Create the Alert Group (ga.*) in the Active Directory
rem (see the "emailaddress" variable below for the name format).
rem Example: ga.servername.backup-notify
rem (This step can be skipped if the email address to which backup
rem reports will be sent already exists.)
rem 4) Modify the Registry so that only one backup log (rather than
rem 10 logs, rotated) is used. To do this, load the registry file
rem ntbackup-onlyonelog.reg (which is usually located in the same
folder as
rem serverbackup.cmd) under the user account that ntbackup will
rem impersonate when conducting its backups.
rem For reference, this is the content of the .reg file (note: two
lines):
rem [HKEY_CURRENT_USER\Software\Microsoft\Ntbackup\Log Files]
rem "Log File Count"=dword:00000001
rem 5) Set up the Scheduled Tasks if Scheduled Tasks are to be used.
rem For each week (or "rotation"), there are normally two Scheduled
Tasks:
rem (assuming a three-week rotation and a 12am start time note
that a
rem three-week rotation would require a total of six Scheduled
Tasks)
rem "Backup Week 1 Normal"
rem Run: c:\active\scripts\serverbackup\serverbackup.cmd 1
normal
rem Schedule: Weekly, every 3 weeks, at 12am on Monday
rem "Backup Week 1 Diff"
rem Run: c:\active\scripts\serverbackup\serverbackup.cmd 1
diff
rem Schedule: Weekly, every 3 weeks, at 12am on Tues, Weds,
Thurs,
rem Fri, and Sat
rem For both:
rem Run as: DOMAINNAMEHERE\Administrator
rem Enabled
rem Rest of the settings = use the defaults
rem The backup script can handle any Scheduled Task configuration,
so the
rem above is just one example of many possible tasks.
rem -----
rem SCRIPT CUSTOMIZATIONS
rem 1) Specify the server to be backed-up
rem
set srvname=servername
rem 2) Specify the names of the files to be placed at the root of the
external
rem backup drives to indicate their eligibility as backup drives:
rem (this is crucial in preventing accidential erasure of data)
rem
set fixedfilename=autobackup-fixed-ok.txt
rem
set rotatedfilename=autobackup-rotated-ok.txt
rem 3a) Specify whether the server needs an Exchange backup:
rem use "true" or "false" (w/o quotes)
rem
set bakexchange=false
rem
rem 3b) If an Exchange backup is specified, on the server in question,
ensure
rem that the exchange.bks file exists, and specify its path:
rem
set exchangebksfile=c:\active\scripts\serverbackup\exchange.bks
rem 4a) Specify whether the server needs to backup a file on another
rem server:
rem use "true" or "false" (w/o quotes)
rem
set bakother=false
rem
rem 4b) If this is the case, then specify the location of the file,
using its
rem full file name and its UNC path:
rem
set otherfile=\\otherservername\c$\backup\otherserver-drivec-
sysstate.bkf
rem
rem 4c) Specify a friendly name for this backup:
rem
set bakothername=otherserver-drivec-sysstate
rem
rem Note: A backup of a file on another server will only be done
during
rem a backup of type normal (i.e. baktype=normal). Be sure that the
user
rem account under which serverbackup.cmd runs has the right to access
rem the other location.
rem 5) Specify the email address that will be used in the From: and
To:
rem fields of the emailed backup report:
rem Example: ga.%srvname%.backup-notify@company.com
rem
set emailaddress=ga.%srvname%.backup-notify@company.com
rem 6) Specify the Exchange email pickup folder. The user account
under
rem which serverbackup.cmd runs must have write access to this
location.
rem For authentication purposes, this location should be in the
same
rem Windows domain as the server on which the backup script is
running.
rem
set exchpickup=\\mailservername\c$\Program Files\Exchsrvr\Mailroot\vsi
1\PickUp
rem -----
rem Note: Carets are used to wrap lines that extend beyond 80
characters.
rem Note: The line "cmd /c exit /b 5" is used to set the errorlevel to
a
rem non-zero value so that we know that the next command
executed
rem at least to the point that a new errorlevel was set.
set weeknum=%1
set baktype=%2
set baktypeabbrev=%baktype%
if /i %baktype%==diff set baktype=differential
set baklog=%temp%\backuplog.log
set robolog=%temp%\robocopylog.log
set emailtop=%temp%\emailtop.txt
set ntbackuplog=%userprofile%\Local Settings\Application ^
Data\Microsoft\Windows NT\NTBackup\data\backup01.log
set ntbackupall=%temp%\ntbackupall.log
rem Delete any pre-existing log files:
del "%baklog%"
del "%ntbackuplog%"
del "%robolog%"
del "%emailtop%"
del "%ntbackupall%"
rem Write the header of the baklog:
echo Starting Server Backup> "%baklog%"
echo.>> "%baklog%"
echo Server, Backup Details, and start Date/Time:>> "%baklog%"
echo %srvname%, Week %weeknum%, Type %baktype%>> "%baklog%"
date /t>> "%baklog%"
time /t>> "%baklog%"
echo.>> "%baklog%"
rem Make sure the script is being run on the correct server
if /i %srvname%==%computername% goto proper-server
echo This script must be run locally on the server to be ^
backed-up.>> "%baklog%"
echo If this is the correct server, then open this script>>
"%baklog%"
echo in notepad and edit the "srvname" variable (the script>>
"%baklog%"
echo believes the file server is %srvname%).>> "%baklog%"
echo Script aborting.>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=Wrong Server
goto end
roper-server
rem Make sure that weeknum (%1) has been specified
if not [%1]==[] goto weeknum-specified
echo Please include the weeknum (a positive integer) when ^
running the script:>> "%baklog%"
echo serverbackup.cmd weeknum baktype>> "%baklog%"
echo Script aborting.>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=Variable weeknum Not Specified
goto end
:weeknum-specified
rem Make sure that baktype (%2) has been specified properly
if %2==normal goto baktype-specified
if %2==diff goto baktype-specified
echo Please include the proper baktype when running ^
the script:>> "%baklog%"
echo serverbackup.cmd weeknum baktype>> "%baklog%"
echo where baktype is: normal or diff>> "%baklog%"
echo Script aborting.>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=Variable baktype Not Specified
goto end
:baktype-specified
rem Check all locally-attached drives to find the fixed (non-rotated)
rem external backup drive, by looking for its tag. This step will
rem find and use the alphabetically-first such drive, even if multiple
rem such drives are attached.
rem
set fixeddriveletter=none
for %%f in (z y x w v u t s r q p o n m l k j i h g f e d) do if ^
exist %%f:\%fixedfilename% set fixeddriveletter=%%f
if not %fixeddriveletter%==none goto fixeddrive-is-ready
echo The external Fixed Drive is not attached or it is not ^
tagged for>> "%baklog%"
echo use by the backup mechanism (the file %fixedfilename
%>>"%baklog%"
echo must exist at the root of the drive).>> "%baklog%"
echo Please take corrective action.>> "%baklog%"
echo Backup aborting.>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=Failure: Fixed Drive Not Ready
goto end
:fixeddrive-is-ready
echo External Fixed Drive, drive %fixeddriveletter%:, is ready.>>
"%baklog%"
echo.>> "%baklog%"
rem If the type of backup is Normal, delete the pre-existing backup
files
rem since backup type Normal implies we are starting a new week:
if /i %baktype%==normal del /q %fixeddriveletter%:\week%weeknum%\*.*
rem If the type of backup is Differential, then we need to know
whether
rem it is the first, second, etc. Differential backup of the week, so
that
rem we don't overwrite any previous Differential backup files. We do
this
rem by checking for preexisting Differential backup files.
rem Note: If there are more than 49 differential backup files, then
this
rem will not operate properly.
if /i %baktype%==normal goto skip-diff-check
for /L %%f in (50,-1,1) do if not exist ^
%fixeddriveletter%:\week%weeknum%\%srvname%-week%weeknum%-diff%%f-sys^
state.bkf set diffnum=%%f
echo Variable diffnum is %diffnum%.>> "%baklog%"
echo.>> "%baklog%"
set baktypeabbrev=diff%diffnum%
:skip-diff-check
rem Backup files have a labeling scheme, which is of the form:
rem servername-week1-diff3
rem This is used in the file name and in the tape name.
rem We represent this with a new variable:
set bakname=%srvname%-week%weeknum%-%baktypeabbrev%
rem -----
rem Run the backup of the System State:
rem The errorlevel entry will help catch if the backup aborts.
set jobname=sysstate
echo Starting backup of %jobname%.>> "%baklog%"
date /t>> "%baklog%"
time /t>> "%baklog%"
echo.>> "%baklog%"
rem Note: system state is always type=Normal.
rem The ntbackup command is sufficiently long that we first prepare
the
rem command as a variable, then we run ntbackup using this variable as
rem the parameter:
set bakss=backup systemstate /n "%bakname%-%jobname%" /d
set bakss=%bakss% "%bakname%-%jobname%" /v:yes /r:no /rs:no /hcff /m
normal
set bakss=%bakss% /j "%jobname%" /l:s /f
set bakss=%bakss% "%fixeddriveletter%:\week%weeknum%\%bakname%-%jobname
%.bkf"
cmd /c exit /b 5
ntbackup %bakss%
set saveerrorlevel=%errorlevel%
type "%ntbackuplog%"> "%ntbackupall%"
echo.>> "%ntbackupall%"
rem Check the errorlevel and notify admin if there is a problem.
if %saveerrorlevel%==0 goto bak-sysstate-ok
echo Backup of %jobname% failed.>> "%baklog%"
echo Check the backup log for details.>> "%baklog%"
echo Backup aborting.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=Failure: Backup of %jobname% failed
goto end
:bak-sysstate-ok
echo Backup of %jobname% completed successfully.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
echo.>> "%baklog%"
rem -----
rem -----
rem Run the backup of the C Drive:
rem The errorlevel entry will help catch if the backup aborts.
set jobname=drivec
echo Starting backup of %jobname%.>> "%baklog%"
date /t>> "%baklog%"
time /t>> "%baklog%"
echo.>> "%baklog%"
rem The ntbackup command is sufficiently long that we first prepare
the
rem command as a variable, then we run ntbackup using this variable as
rem the parameter:
set bakdc=backup c:\ /n "%bakname%-%jobname%" /d "%bakname%-%jobname%"
set bakdc=%bakdc% /v:yes /r:no /rs:no /hcff /m %baktype% /j "%jobname
%"
set bakdc=%bakdc% /l:s /f
set bakdc=%bakdc% "%fixeddriveletter%:\week%weeknum%\%bakname%-%jobname
%.bkf"
cmd /c exit /b 5
ntbackup %bakdc%
set saveerrorlevel=%errorlevel%
type "%ntbackuplog%">> "%ntbackupall%"
echo.>> "%ntbackupall%"
rem Check the errorlevel and notify admin if there is a problem.
if %saveerrorlevel%==0 goto bak-drivec-ok
echo Backup of %jobname% failed.>> "%baklog%"
echo Check the backup log for details.>> "%baklog%"
echo Backup aborting.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=Failure: Backup of %jobname% failed
goto end
:bak-drivec-ok
echo Backup of %jobname% completed successfully.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
echo.>> "%baklog%"
rem -----
rem -----
rem The next step is to back-up Exchange data, but only if the
rem bakexchange variable is set to true:
if not %bakexchange%==true goto skip-bakexchange
rem Run the backup of the Exchange database:
rem The errorlevel entry will help catch if the backup aborts.
set jobname=exchange
echo Starting backup of %jobname%.>> "%baklog%"
date /t>> "%baklog%"
time /t>> "%baklog%"
echo.>> "%baklog%"
rem The ntbackup command is sufficiently long that we first prepare
the
rem command as a variable, then we run ntbackup using this variable as
rem the parameter:
set bakex=backup "@%exchangebksfile%" /n "%bakname%-%jobname%" /d
set bakex=%bakex% "%bakname%-%jobname%" /v:yes /r:no /rs:no /hcff /m
set bakex=%bakex% %baktype% /j "%jobname%" /l:s /f
set bakex=%bakex% "%fixeddriveletter%:\week%weeknum%\%bakname%-%jobname
%.bkf"
cmd /c exit /b 5
ntbackup %bakex%
set saveerrorlevel=%errorlevel%
type "%ntbackuplog%">> "%ntbackupall%"
echo.>> "%ntbackupall%"
rem Check the errorlevel and notify admin if there is a problem.
if %saveerrorlevel%==0 goto bak-exchange-ok
echo Backup of %jobname% failed.>> "%baklog%"
echo Check the backup log for details.>> "%baklog%"
echo Backup aborting.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=Failure: Backup of %jobname% failed
goto end
:bak-exchange-ok
echo Backup of %jobname% completed successfully.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
echo.>> "%baklog%"
:skip-bakexchange
rem -----
rem -----
rem This next step allows the local server to backup a file
rem on another computer (usually a .bkf file representing a
rem backup generated locally on that other computer), but
rem only if the bakother variable is set to true:
if not %bakother%==true goto skip-bakother
rem This backup will only be done during a normal backup.
if not %baktype%==normal goto skip-bakother
set jobname=%bakothername%
echo Starting backup of %jobname%.>> "%baklog%"
date /t>> "%baklog%"
time /t>> "%baklog%"
echo.>> "%baklog%"
cmd /c exit /b 5
copy "%otherfile%" %fixeddriveletter%:\week%weeknum%
set saveerrorlevel=%errorlevel%
rem Check the errorlevel and notify admin if there is a problem.
if %saveerrorlevel%==0 goto bakother-ok
echo Backup %jobname% failed.>> "%baklog%"
echo Backup aborting.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=Failure: Backup of %jobname% failed
goto end
:bakother-ok
echo Backup of %jobname% completed successfully.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
echo.>> "%baklog%"
:skip-bakother
rem -----
rem Now that all of the backups have completed, let's check the
rem ntbackup logs (which are all contained in the file that is
rem represented by the "ntbackupall" variable) for mention of
rem any errors that - for whatever reason - did not cause
rem ntbackup to generate a formal errorlevel alert.
rem Note: You may manually add additional findstr commands (simply
rem repeat the two-line block and use a different search string). Be
rem sure to test any additions to ensure that they do not detect
valid
rem log entries.
findstr /i /c:"error " "%ntbackupall%"
if not errorlevel 1 goto ntbackuplogerror-failure
findstr /i /c:"error:" "%ntbackupall%"
if not errorlevel 1 goto ntbackuplogerror-failure
findstr /i /c:"The operation did not successfully complete."
"%ntbackupall%"
if not errorlevel 1 goto ntbackuplogerror-failure
findstr /i /c:"Insufficient disk space." "%ntbackupall%"
if not errorlevel 1 goto ntbackuplogerror-failure
goto ntbackuplogerror-success
:ntbackuplogerror-failure
set fatalerror=Failure: ntbackup Error (see "ntbackup log" section)
goto end
:ntbackuplogerror-success
rem Check all locally-attached drives to find the rotated
rem external backup drive, by looking for its tag. This step will
rem find and use the alphabetically-first such drive, even if multiple
rem such drives are attached. This step will double-check that one
rem external drive is not tagged as both the Fixed Drive and the
rem Rotated Drive.
rem
set rotateddriveletter=none
for %%f in (z y x w v u t s r q p o n m l k j i h g f e d) do if ^
exist %%f:\%rotatedfilename% set rotateddriveletter=%%f
if not %rotateddriveletter%==none goto rotateddrive-is-ready
echo The external Rotated Drive is not attached or it is not ^
tagged for>> "%baklog%"
echo use by the backup mechanism (the file %rotatedfilename
%>>"%baklog%"
echo must exist at the root of the drive).>> "%baklog%"
echo Please take corrective action.>> "%baklog%"
echo Backup aborting.>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=Failure: Rotated Drive Not Ready
goto end
if not %rotateddriveletter%==%fixeddriveletter% goto rotateddrive-is-
ready
echo One drive, drive %rotateddriveletter%:, is tagged as both the
^
Fixed Drive>> "%baklog%"
echo and the Rotated Drive. This is not allowed. Please take ^
corrective action>> "%baklog%"
echo (usually by deleting one of the file tags at the root of the
^
drive).>> "%baklog%"
echo Backup aborting.>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=Failure: Rotated Drive is also the Fixed Drive
goto end
:rotateddrive-is-ready
echo External Rotated Drive, drive %rotateddriveletter%:, is ^
ready.>> "%baklog%"
echo.>> "%baklog%"
rem Run the robocopy command.
echo Starting Fixed-to-Rotated Copy Operation.>> "%baklog%"
date /t>> "%baklog%"
time /t>> "%baklog%"
echo.>> "%baklog%"
rem The robocopy command is sufficiently long that we first prepare
the
rem command as a variable, then we run robocopy using this variable as
rem the parameter:
set robocmd=%fixeddriveletter%: %rotateddriveletter%: /mir /xd
set robocmd=%robocmd% %fixeddriveletter%:\RECYCLER
set robocmd=%robocmd% "%fixeddriveletter%:\System Volume Information"
set robocmd=%robocmd% %rotateddriveletter%:\RECYCLER
set robocmd=%robocmd% "%rotateddriveletter%:\System Volume
Information"
set robocmd=%robocmd% /xf %fixeddriveletter%:\%fixedfilename%
set robocmd=%robocmd% %rotateddriveletter%:\%rotatedfilename%
set robocmd=%robocmd% /log:"%robolog%" /tee /np
cmd /c exit /b 100
robocopy %robocmd%
set saveerrorlevel=%errorlevel%
rem Check the errorlevel of the robocopy command and notify admin if
a
rem problem occurred.
rem Errorlevels 0-3 are OK.
if %saveerrorlevel% LEQ 3 goto robocopy-checktwo
goto robocopy-failure
:robocopy-checktwo
if %saveerrorlevel% GEQ 0 goto robocopy-success
:robocopy-failure
echo The copy operation from %fixeddriveletter%: to ^
%rotateddriveletter%: failed.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
echo (Errorlevels 0-3 are OK)>> "%baklog%"
echo Check the logs for details.>> "%baklog%"
echo Backup Aborting>> "%baklog%"
date /t>> "%baklog%"
time /t>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=Failure: Fixed-to-Rotated Copy Operation Failed
goto end
:robocopy-success
echo Fixed-to-Rotated Copy Operation Successful.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
echo (Errorlevels 0-3 are OK)>> "%baklog%"
date /t>> "%baklog%"
time /t>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=Success: Backup Successful
rem If the backup process has gone this far, then it means that
rem both external drives are properly attached. So, at this
rem point (when all priority backup and mirroring operations are
complete),
rem if the type of backup is Normal, then we will run a chkdsk (in
read-only
rem mode) on both external drives to check their status.
rem Write notice of any possible errors to baklog and fatalerror.
if not %baktype%==normal goto skip-chkdsk
echo Starting chkdsk of Fixed drive, drive %fixeddriveletter%:.>>
"%baklog%"
echo.>> "%baklog%"
cmd /c exit /b 5
chkdsk %fixeddriveletter%:
set saveerrorlevel=%errorlevel%
if %saveerrorlevel%==0 goto chk-fixeddrive-okay
echo chkdsk detected possible errors on the Fixed Drive, ^
drive %fixeddriveletter%:.>> "%baklog%"
echo With this drive attached, run chkdsk %fixeddriveletter%: ^
/f /r /x on %srvname%>> "%baklog%"
echo as soon as possible.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
date /t>> "%baklog%"
time /t>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=%fatalerror% but see chkdsk for Fixed Drive
goto skip-chk-fixeddrive-okay
:chk-fixeddrive-okay
echo chkdsk of Fixed drive, drive %fixeddriveletter%:, reported no ^
errors.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
date /t>> "%baklog%"
time /t>> "%baklog%"
echo.>> "%baklog%"
:skip-chk-fixeddrive-okay
echo Starting chkdsk of Rotated drive, drive ^
%rotateddriveletter%:.>> "%baklog%"
echo.>> "%baklog%"
cmd /c exit /b 5
chkdsk %rotateddriveletter%:
set saveerrorlevel=%errorlevel%
if %saveerrorlevel%==0 goto chk-rotateddrive-okay
echo chkdsk detected possible errors on the Rotated Drive, drive ^
%rotateddriveletter%:.>> "%baklog%"
echo With this drive attached, run chkdsk %rotateddriveletter%: ^
/f /r /x on %srvname%>> "%baklog%"
echo as soon as possible.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
date /t>> "%baklog%"
time /t>> "%baklog%"
echo.>> "%baklog%"
set fatalerror=%fatalerror% but see chkdsk for Rotated Drive
goto skip-chk-rotateddrive-okay
:chk-rotateddrive-okay
echo chkdsk of Rotated drive, drive %rotateddriveletter%:, reported no
^
errors.>> "%baklog%"
echo Errorlevel is %saveerrorlevel%.>> "%baklog%"
date /t>> "%baklog%"
time /t>> "%baklog%"
echo.>> "%baklog%"
:skip-chk-rotateddrive-okay
:skip-chkdsk
:end
rem Build the summary email for the admin and send it using an
Exchange
rem email pickup folder.
echo X-sender: %emailaddress%> "%emailtop%"
echo x-receiver: %emailaddress%>> "%emailtop%"
echo From: %emailaddress%>> "%emailtop%"
echo To: %emailaddress%>> "%emailtop%"
echo Subject: Backup of %srvname%: %fatalerror%>> "%emailtop%"
echo.>> "%emailtop%"
echo Server Backup Report for %srvname%>> "%emailtop%"
echo Status message is: %fatalerror%>> "%emailtop%"
echo.>> "%emailtop%"
echo --------------- start backup script log -------------->>
"%emailtop%"
echo.>> "%emailtop%"
type "%baklog%">> "%emailtop%"
echo.>> "%emailtop%"
echo ----------------- start ntbackup log ----------------->>
"%emailtop%"
echo.>> "%emailtop%"
type "%ntbackupall%">> "%emailtop%"
echo.>> "%emailtop%"
echo ----------------- start robocopy log ----------------->>
"%emailtop%"
echo.>> "%emailtop%"
type "%robolog%">> "%emailtop%"
echo.>> "%emailtop%"
echo ---------------- end of Backup Report ---------------->>
"%emailtop%"
echo.>> "%emailtop%"
copy "%emailtop%" "%exchpickup%"
rem Delete the log files
del "%baklog%"
del "%ntbackuplog%"
del "%robolog%"
del "%emailtop%"
del "%ntbackupall%"
rem End of Backup Script