Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 'Live File Backup Script v1.2
- 'Written by Aaron Loessberg-Zahl
- 'Last modified 03 April 2012
- '
- '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.
- '
- '_ _ _ ____ ____ _ _ _ _ _ ____ /
- '| | | |__| |__/ |\ | | |\ | | __ /
- '|_|_| | | | \ | \| | | \| |__] .
- '
- '!!THIS SCRIPT DOES NOT RECURSE DOWN FOLDER TREES PROPERLY!!
- '
- 'I did not realize until after writing this script that VBScript does not do
- 'recursion properly. For example, when calling folderCompareAndCopy
- 'recursively, strDestFolder will be overwritten by the subsequent calls, causing
- 'files to be placed in weird locations in the backup destination. This only
- 'occurs with a directory tree of depth > 2. For example, running
- 'cscript liveBackup.vbs "C:\Source" <some_destination> on the following tree is
- 'okay:
- '
- ' C:
- ' |_Source
- ' |_Folder A
- ' | |_File 1
- ' | |_File 2
- ' |_Folder B
- ' |_File 3
- ' |_File 4
- '
- 'Anything deeper will produce errors in the destination.
- '
- '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.2 04-03-2012 amloessb Broken script is broken
- '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 oDestCDM, oSrcCDM, strSrcCDM, strDestCDM
- Dim oDestFCDM, oSrcFCDM, strSrcFCDM, strDestFCDM, strDestFolderFCDM, fileFCDM, subfolderFCDM
- Dim oSrcCC, oDestCC, destCC
- Dim oSrcFCC, oDestFCC, destFCC, fileFCC, subfolderFCC
- 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 (strSrcCDM, strDestCDM, strMsg)
- If objFSO.FileExists(strDestCDM) Then
- Set oDestCDM = objFSO.GetFile(strDestCDM)
- Set oSrcCDM = objFSO.GetFile(objFSO.BuildPath(strSrcCDM,oDestCDM.Name))
- dateSrcModified = oSrcCDM.DateLastModified
- dateDestModified = oDestCDM.DateLastModified
- If dateDestModified > dateSrcModified Then
- compareDateModified = strMsg & oSrcCDM.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 (strSrcFCDM, strDestFCDM, strMsg)
- If objFSO.FolderExists(strDestFCDM) Then
- Set oSrcFCDM = objFSO.GetFolder(strSrcFCDM)
- Set oDestFCDM = objFSO.GetFolder(strDestFCDM)
- For Each fileFCDM In oSrcFCDM.Files
- strMsg = compareDateModified(strSrcFCDM, objFSO.BuildPath(strDestFCDM, fileFCDM.Name), strMsg)
- Next
- For Each subfolderFCDM In objFSO.GetFolder(strSrcFCDM).SubFolders
- strDestFolderFCDM = objFSO.BuildPath(strDestFCDM, subfolderFCDM.Name)
- strMsg = folderCompareDateModified (subfolderFCDM.Path, objFSO.BuildPath(strDestFolderFCDM, subfolderFCDM.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 (oSrcCC, oDestCC, destCC)
- 'Failsafe (source and destination names must match)
- If Not oSrcCC.Name = oDestCC.Name Then
- WScript.Echo "FAIL: " & oSrcCC.Name & " != " & oDestCC.Name
- WScript.Quit 2
- End If
- dateSrcModified = oSrcCC.DateLastModified
- dateDestModified = oDestCC.DateLastModified
- If dateSrcModified > dateDestModified Or Not oSrcCC.Size = oDestCC.Size Then
- oSrcCC.Copy destCC, True
- Call printCopyInfo(oSrcCC)
- 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 (oSrcFCC, oDestFCC, destFCC)
- 'Failsafe (source and destination names must match)
- 'WScript.Echo destFCC
- 'WScript.Echo "- " & oSrcFCC
- 'WScript.Echo "- " & oDestFCC
- If Not oSrcFCC.Name = oDestFCC.Name Then
- WScript.Echo "FAIL: " & oSrcFCC.Name & " != " & oDestFCC.Name
- WScript.Quit 2
- End If
- Set objSubFol = oSrcFCC.SubFolders
- Set objSubFiles = oSrcFCC.Files
- 'Recursion end case: individual files
- For Each fileFCC In objSubFiles
- strDestFolder = oDestFCC.Path
- strDestFolder = fixFolderStr(strDestFolder)
- strDestFile = objFSO.BuildPath(oDestFCC.Path, fileFCC.Name)
- If Not objFSO.FileExists(strDestFile) Then
- objFSO.CreateTextFile strDestFile
- End If
- Set objDestFile = objFSO.GetFile(strDestFile)
- Call compareAndCopy(fileFCC, objDestFile, strDestFolder)
- Next
- 'Recurse through all subfolders
- For Each subfolderFCC In objSubFol
- 'WScript.Echo VBTab & oSrcFCC.Name & "->" & subfolderFCC.Name
- 'WScript.Echo VBTab & subfolderFCC.ParentFolder.Name & "->" & subfolderFCC.Name
- strDestFolder = objFSO.BuildPath(oDestFCC.Path, subfolderFCC.Name)
- If Not objFSO.FolderExists(strDestFolder) Then
- objFSO.CreateFolder(strDestFolder)
- End If
- Set objDestFolder = objFSO.GetFolder(strDestFolder)
- Call folderCompareAndCopy(subfolderFCC, objDestFolder, oDestFCC.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