Scheduling a Windows ASR backup


In Windows Server 2003 and Windows XP, ntbackup’s ASR is a great method of backing up the entire system for disaster recovery. This week I wrote a script to schedule a Windows ASR backup using the command-line ntbackup.exe utility. If you’ve ever written a how-to on VBscript, I probably have read it. Thanks! Of note is the fact that the ASR call for ntbackup is not actually documented, so use this at your own risk, but it’s working very well for me now. Naturally I take no responsibility for anything that happens due to the use of this script, but if it helps, then let me know in the comments.

What the script does:

  • Starts an ASR backup and saves it to a network location using the computer name and and current date for the filename.
  • Monitors the file writing progress to figure out when the file has stopped being written to, and then kills ntbackup.exe (this is because ntbackup will wait for a floppy to be inserted, and thus hang around forever).
  • Deletes any backups matching the computer name that are older than a certain threshold. This can be turned off.

Copy the below, paste it into something.vbs and then edit it. Run when you’re ready. I’ve scheduled this on my servers to handle ASR backups’ monthly. It works great… that is until I upgrade to Server 2008 and have to figure something else out. If you have any difficulties with the script, you can uncomment the Wscript.echo lines and it will give you some output. If you wanted you could also record that output to a logging file, I guess. Actually… you could also email the output pretty easily, if you wanted to do that to. There’s an idea…

'The purpose of this script is to generate a full computer backup using Windows ASR (via ntbackup).
'An ASR backup will automatically write ASR files to a floppy disk if it's in the drive, so this script
'waits till the backup has finished, and then kills ntbackup.exe so there are no instances hanging around.
'Note that ntbackup will probably overwrite any files on your floppy, so use this with caution.
'This script also has an option to delete older backups with a filename matching the current structure,
'provided the backup is older than a certain threshold. Options are below.
'Credits: Thanks to just about everyone who has written a VBscript how-to online.

Dim BackupServer, BackupPath, BackupLocation, BackupFilePath, BackupCall, WaitTimeForBackupCommence, WaitTimeForWrites, WaitTimeToRecheck, MaxBackupAge

' ************ USER CONFIGURABLE SETTINGS ****************

BackupServer = "servername" 'specify your servername ex: "backupserver.domain.com"
BackupPath = "f$\ASRs\" 'specify your folder path, must include trailing slash ex: "G$\ASR-backups\"
WaitTimeForBackupCommence = 600000 'how long to wait after the backup has started before we start looking to see if the backup is finished
WaitTimeForWrites = 30000 'how long to wait between file checks (the filesize is checked to see if it has stopped growing)
WaitTimeToRecheck = 300000 'how long to wait before we start checking the filesize once again, in case was still growing
DeleteOldBackups = true 'set to True or False depending on if you want the script to clean up older backups or not
MaxBackupAge = 45 'days to keep backups for
' ************** END OF USER CONFIGURABLE SETTINGS ***********

Set WshNetwork = WScript.CreateObject("WScript.Network")
BackupLocation = "\\" & BackupServer & "\" & BackupPath
BackupFilePath = BackupLocation & WshNetwork.ComputerName & "_" & Datepart("yyyy", cDate(Date)) & "-" & Datepart("m", cDate(Date)) & "-" & Datepart("d", cDate(Date)) & ".bkf"
BackupCall = "ntbackup asrbackup /f """ & BackupFilePath & """"

Set wshShell = WScript.CreateObject ("WSCript.shell")
wshShell.run BackupCall
set wshShell = nothing

'Ssleep duration sufficient for the file creation to begin, maybe 5 minutes
'WScript.Echo "sleeping"
WScript.Sleep(WaitTimeForBackupCommence)

Dim stoploop
stoploop = 0
While stoploop = 0

'WScript.Echo "looping"

Dim Filesys1, BackupFile1, BackupFileSize1
Set Filesys1 = CreateObject("Scripting.FileSystemObject")
Set BackupFile1 = Filesys1.GetFile(BackupFilePath)
BackupFileSize1 = BackupFile1.Size
'WScript.Echo "filesize is " & BackupFileSize1

'WScript.Echo "sleeping"
'Sleep duration to check for file size change
WScript.Sleep(WaitTimeForWrites)

Dim Filesys2, BackupFile2, BackupFileSize2
Set Filesys2 = CreateObject("Scripting.FileSystemObject")
Set BackupFile2 = Filesys2.GetFile(BackupFilePath)
BackupFileSize2 = BackupFile2.Size
'WScript.Echo "filesize is " & BackupFileSize2

If BackupFileSize2 = BackupFileSize1 Then
stoploop = 1
'WScript.Echo "file has stopped growing. ending script"
Else
stoploop = 0
'WScript.Echo "file is still growing. looping again"
Set BackupFile1 = nothing
Set BackupFile2 = nothing
'WScript.Echo "sleeping"
'Sleep duration to wait for checking for file size change again
WScript.Sleep(WaitTimeToRecheck)
End If
Wend

'WScript.Echo "Killing NTBackup..."

strComputer = "."
strProcessToKill = "ntbackup.exe"

SET objWMIService = GETOBJECT("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")

SET colProcess = objWMIService.ExecQuery _
("Select * from Win32_Process Where Name = '" & strProcessToKill & "'")

count = 0
FOR EACH objProcess in colProcess
objProcess.Terminate()
count = count + 1
NEXT

'WScript.Echo "Killed " & count & " instances of " & _
strProcessToKill

'only delete files if delete=true
if DeleteOldBackups = true Then

Dim fso
Dim oFolder
Dim oFile
Dim oSubFolder

Set fso = createobject("Scripting.FileSystemObject")
Set oFolder = fso.GetFolder(BackupLocation)
For Each oFile In oFolder.files
If DateDiff("d", oFile.DateCreated,Now) > MaxBackupAge Then
If Instr(1,oFile.Name,WshNetwork.ComputerName,1) Then
oFile.Delete True
End If
End If
Next

''WScript.Echo "finished deleting stuff"

End if

''WScript.Echo "not deleting stuff today"

WScript.Quit