Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 'Live File Backup Script v1.1.1
- 'Written by Aaron Loessberg-Zahl
- 'Last modified 11 Nov 2011
- '
- 'Copies files from a source directory (or a single source file)
- 'to a backup destination as they are changed in the source.
- '
- 'This script must be run from the command line.
- '
- 'For comments/questions/bugs, please contact
- '<[email protected]> or <[email protected]>.
- '
- ' ----------------------------------------------------------------------------
- ' "THE BEER-WARE LICENSE" (Revision 2659):
- ' <[email protected]> wrote this file. As long as you retain this
- ' notice, you can do whatever you want with this stuff. If we meet some day,
- ' and you think this stuff is worth it, you can buy me a beer in return.
- ' ----------------------------------------------------------------------------
- '
- 'Changelog:
- 'v1.1.1 11-11-2011 amloessb Further fixed interval checking
- 'v1.1 11-11-2011 amloessb Added check for non-numeric interval
- 'v1.0 11-09-2011 amloessb First working version
- Option Explicit
- Dim objFSO, objSource, objDest, objChildren, objFiles, objDestFile, args
- Dim strSource, strDest, strDestFile, strFilename, strChoice, strAnswer, strHeader
- Dim subfolder, file, strDestFolder, objDestFolder, strNewFileList, strSize, strName
- Dim dateSrcModified, dateDestModified, dateModified
- Dim badAnswer, newFiles, isFileOp
- Dim objSubFol, objSubFiles, oSrc, oDest
- Dim intInterval
- Dim DTab, TTab
- 'ynAnswer ()
- 'Purpose: Reads in an answer from StdIn, and loops if it is not "y" or "n"
- ' The case of the user's answer does not matter.
- 'Returns: the answer "y" or "n"
- Function ynAnswer ()
- badAnswer = True
- While badAnswer
- WScript.StdIn.Read(0)
- strChoice = WScript.StdIn.ReadLine()
- If Lcase(strChoice) = "n" Then
- ynAnswer = "n"
- badAnswer = False
- ElseIf Lcase(strChoice) = "y" Then
- ynAnswer = "y"
- badAnswer = False
- Else
- WScript.StdOut.Write "Please answer y or n > "
- End If
- WEnd
- End Function
- 'confirmOp (src, dest, fileOp)
- 'Purpose: Asks the user to confirm the backup settings
- 'Returns: N/A
- 'Depends on ynAnswer
- Function confirmOp (src, dest, fileOp)
- WScript.StdOut.Write "The script will now backup "
- If Not fileOp Then
- WScript.StdOut.Write "the contents of" & VBCrLf
- Else
- WScript.StdOut.Write VBCrLf
- End If
- WScript.Echo src
- WScript.Echo "to"
- WScript.Echo dest
- WScript.Echo ""
- WScript.StdOut.Write "Is this correct? [y/n] > "
- strAnswer = ynAnswer()
- If strAnswer = "n" Then
- WScript.Quit 0
- End If
- End Function
- 'printCopyInfo (src)
- 'Purpose: Prints the time, name, and size of the given file or folder
- 'Returns: N/A
- Function printCopyInfo (src)
- dateModified = src.DateLastModified
- strSize = FormatNumber((src.Size / 1024.0), 2)
- strName = src.Name
- 'WScript.StdOut.Write VBCrLf
- WScript.Echo dateModified & VBTab & strName & VBTab & strSize & "K"
- End Function
- 'compareDateModified (strSrc, strDest, strMsg)
- 'Purpose: Appends the file information to strMsg if the dest file is newer
- 'Returns: strMsg, with the file's entry appended if the dest file is newer
- Function compareDateModified (strSrc, strDest, strMsg)
- If objFSO.FileExists(strDest) Then
- Set oDest = objFSO.GetFile(strDest)
- Set oSrc = objFSO.GetFile(objFSO.BuildPath(strSrc,oDest.Name))
- dateSrcModified = oSrc.DateLastModified
- dateDestModified = oDest.DateLastModified
- If dateDestModified > dateSrcModified Then
- compareDateModified = strMsg & oSrc.Name & DTab & dateSrcModified & _
- DTab & dateDestModified & VBCrLf
- End If
- End If
- End Function
- 'folderCompareDateModified (strSrc, strDest, strMsg)
- 'Purpose: Recursive compareDateModified, by folder
- 'Returns: strMsg, appended to as necessary
- 'Depends on compareDateModified
- Function folderCompareDateModified (strSrc, strDest, strMsg)
- If objFSO.FolderExists(strDest) Then
- Set oSrc = objFSO.GetFolder(strSrc)
- Set oDest = objFSO.GetFolder(strDest)
- For Each file In oSrc.Files
- strMsg = compareDateModified(strSrc, objFSO.BuildPath(strDestFolder, file.Name), strMsg)
- Next
- For Each subfolder In objFSO.GetFolder(strSrc).SubFolders
- strDestFolder = objFSO.BuildPath(strDest, subfolder.Name)
- strMsg = folderCompareDateModified (subfolder.Path, objFSO.BuildPath(strDestFolder, subfolder.Name), strMsg)
- Next
- End If
- folderCompareDateModified = strMsg
- End Function
- 'compareAndCopy (oSrc, oDest, dest)
- 'Purpose: Copies oSrc to dest if oSrc is newer. 'dest' is the folder that oSrc
- ' will be copied into, while oDest is the file/folder that oSrc will be
- ' replacing.
- 'Returns: N/A
- Function compareAndCopy (oSrc, oDest, dest)
- 'Failsafe (source and destination names must match)
- If Not oSrc.Name = oDest.Name Then
- WScript.Echo "FAIL: " & oSrc.Name & " != " & oDest.Name
- WScript.Quit 2
- End If
- dateSrcModified = oSrc.DateLastModified
- dateDestModified = oDest.DateLastModified
- If dateSrcModified > dateDestModified Or Not oSrc.Size = oDest.Size Then
- oSrc.Copy dest, True
- Call printCopyInfo(oSrc)
- Else
- 'WScript.StdOut.Write "."
- End If
- End Function
- 'folderCompareAndCopy (oSrc, oDest, dest)
- 'Purpose: Recursive compareAndCopy, by folder
- 'Returns: N/A
- 'Depends on compareAndCopy
- Function folderCompareAndCopy (oSrc, oDest, dest)
- 'Failsafe (source and destination names must match)
- If Not oSrc.Name = oDest.Name Then
- WScript.Echo "FAIL: " & oSrc.Name & " != " & oDest.Name
- WScript.Quit 2
- End If
- Set objSubFol = oSrc.SubFolders
- Set objSubFiles = oSrc.Files
- 'Recursion end case: individual files
- For Each file In objSubFiles
- strDestFolder = oDest.Path
- strDestFolder = fixFolderStr(strDestFolder)
- strDestFile = objFSO.BuildPath(oDest.Path, file.Name)
- If Not objFSO.FileExists(strDestFile) Then
- objFSO.CreateTextFile strDestFile
- End If
- Set objDestFile = objFSO.GetFile(strDestFile)
- Call compareAndCopy(file, objDestFile, strDestFolder)
- Next
- 'Recurse through all subfolders
- For Each subfolder In objSubFol
- strDestFolder = objFSO.BuildPath(oDest.Path, subfolder.Name)
- If Not objFSO.FolderExists(strDestFolder) Then
- objFSO.CreateFolder(strDestFolder)
- End If
- Set objDestFolder = objFSO.GetFolder(strDestFolder)
- Call folderCompareAndCopy(subfolder, objDestFolder, oDest.Path)
- Next
- End Function
- 'fixFolderStr (folder)
- 'Purpose: Put a trailing \ on the folder path if it's missing
- 'Returns: The correctrd path string
- Function fixFolderStr (folder)
- If Not Mid(folder,Len(folder),1) = "\" Then
- fixFolderStr = folder & "\"
- Else
- fixFolderStr = folder
- End If
- End Function
- '---MAIN FUNCTION START---
- Set args = WScript.Arguments
- DTab = VBTab & VBTab
- TTab = VBTab & VBTab & VBTab
- badAnswer = True
- newFiles = False
- strHeader = "Name" & TTab & "Source Date"& TTab & "Destination Date"
- strNewFileList = ""
- intInterval = 5
- 'Print the usage statement
- If Not (WScript.Arguments.Count = 2 Or WScript.Arguments.Count = 3) Then
- WScript.Echo ""
- WScript.Echo "Usage: cscript liveBackup.vbs <source> <destination> [interval]"
- WScript.Echo ""
- WScript.Echo "Checks the source every {interval} seconds for changes, and copies changed"
- WScript.Echo "files to the destination. Folder hierarchies are preserved."
- WScript.Echo ""
- WScript.Echo "Arguments:"
- WScript.Echo "source - the source directory or file to be backed up"
- WScript.Echo "destination - the destination directory where the backup will be saved"
- WScript.Echo "interval - the frequency (in seconds) at which the script will check"
- WScript.Echo " for changes in the source (default: 5)"
- WScript.Quit 1
- End If
- strSource = args(0)
- strDest = args(1)
- If WScript.Arguments.Count = 3 Then
- If IsNumeric(args(2)) Then
- intInterval = args(2)
- Else
- WScript.Echo "The supplied interval is not a number."
- WScript.Echo "Using the default interval of 5 seconds."
- End If
- End If
- Set objFSO = CreateObject("Scripting.FileSystemObject")
- If objFSO.FolderExists(strDest) Then
- Set objDest = objFSO.GetFolder(strDest)
- If objFSO.FolderExists(strSource) Then
- 'Directory backup mode
- isFileOp = False
- Set objDest = objFSO.GetFolder(strDest)
- Set objSource = objFSO.GetFolder(strSource)
- Set objChildren = objSource.SubFolders
- Set objFiles = objSource.Files
- 'Check for new folders in the destination
- For Each subfolder In objChildren
- strDestFolder = objFSO.BuildPath(strDest, subfolder.Name)
- strNewFileList = folderCompareDateModified (subfolder.Path, strDestFolder, strNewFileList)
- Next
- 'Check for new files in the destination
- For Each file In objFiles
- strDestFile = objFSO.BuildPath(strDest, file.Name)
- strNewFileList = compareDateModified (strSource, strDestFile, strNewFileList)
- Next
- 'If there are newer folders/files in the dest, print list
- If Not strNewFileList = "" Then
- WScript.Echo strHeader
- WScript.Echo strNewFileList
- WScript.Echo "The above files are newer at the destination then at the source."
- WScript.Echo "You will lose any changes you have made to the destination files"
- WScript.Echo "if you choose to continue."
- WScript.Echo ""
- WScript.StdOut.Write "Would you like to continue anyway? [y/n] > "
- strAnswer = ynAnswer()
- If strAnswer = "n" Then
- WScript.Quit 0
- End If
- End If
- 'Put a trailing \ on the destination path if it's missing
- strDest = fixFolderStr(strDest)
- 'Confirm the operation
- Call confirmOp(strSource, strDest, isFileOp)
- 'Do the initial copy
- For Each subfolder In objChildren
- subfolder.Copy strDest, True
- Next
- For Each file In objFiles
- file.Copy strDest, True
- Next
- WScript.Echo "The script is now actively backing up your files."
- WScript.Echo "Press ^C to stop."
- 'MAIN BACKUP LOOP (directory mode)
- While True
- For Each subfolder In objChildren
- strDestFolder = objFSO.BuildPath(strDest, subfolder.Name)
- If Not objFSO.FolderExists(strDestFolder) Then
- objFSO.CreateFolder(strDestFolder)
- End If
- Set objDestFolder = objFSO.GetFolder(strDestFolder)
- Call folderCompareAndCopy(subfolder, objDestFolder, strDest)
- Next
- For Each file In objFiles
- strDestFile = objFSO.BuildPath(strDest, file.Name)
- If Not objFSO.FileExists(strDestFile) Then
- objFSO.CreateTextFile strDestFile
- End If
- Set objDestFile = objFSO.GetFile(strDestFile)
- Call compareAndCopy(file, objDestFile, strDest)
- Next
- 'WScript.StdOut.Write "."
- WScript.Sleep(1000 * intInterval)
- WEnd
- ElseIf objFSO.FileExists(strSource) Then
- 'File backup mode
- isFileOp = True
- Set objSource = objFSO.GetFile(strSource)
- strFilename = objSource.Name
- strDestFile = objFSO.BuildPath(strDest, strFilename)
- 'Check for a newer file in the destination
- strNewFileList = compareDateModified (strSource, strDestFile, strNewFileList)
- If Not strNewFileList = "" Then
- 'Destination file is newer than the source
- WScript.Echo strHeader
- WScript.Echo strNewFileList
- WScript.Echo "The above files are newer at the destination then at the source."
- WScript.Echo "You will lose any changes you have made to the destination files"
- WScript.Echo "if you choose to continue."
- WScript.Echo ""
- WScript.StdOut.Write "Would you like to continue anyway? [y/n] > "
- strAnswer = ynAnswer()
- If strAnswer = "n" Then
- WScript.Quit 0
- End If
- End If
- 'Put a trailing \ on the destination path if it's missing
- strDest = fixFolderStr(strDest)
- 'Confirm the operation
- Call confirmOp(strSource, strDest, isFileOp)
- 'Do the initial copy
- objSource.Copy strDest, True
- Set objDestFile = objFSO.GetFile(strDestFile)
- WScript.Echo "The script is now actively backing up your files."
- WScript.Echo "Press ^C to stop."
- 'MAIN BACKUP LOOP (file mode)
- While True
- Call compareAndCopy(objSource, objDestFile, strDest)
- 'WScript.StdOut.Write "."
- WScript.Sleep(1000 * intInterval)
- WEnd
- End If
- Else
- WScript.Echo "The destination directory does not exist or is not a directory."
- WScript.Echo strDest
- WScript.Quit 1
- End If
Add Comment
Please, Sign In to add comment