amloessb

liveBackup.vbs (v1.1.1)

Nov 11th, 2011
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. 'Live File Backup Script v1.1.1
  2. 'Written by Aaron Loessberg-Zahl
  3. 'Last modified 11 Nov 2011
  4. '
  5. 'Copies files from a source directory (or a single source file)
  6. 'to a backup destination as they are changed in the source.
  7. '
  8. 'This script must be run from the command line.
  9. '
  10. 'For comments/questions/bugs, please contact
  11. '
  12. ' ----------------------------------------------------------------------------
  13. ' "THE BEER-WARE LICENSE" (Revision 2659):
  14. ' <[email protected]> wrote this file. As long as you retain this
  15. ' notice, you can do whatever you want with this stuff. If we meet some day,
  16. ' and you think this stuff is worth it, you can buy me a beer in return.
  17. ' ----------------------------------------------------------------------------
  18. '
  19. 'Changelog:
  20. 'v1.1.1  11-11-2011  amloessb  Further fixed interval checking
  21. 'v1.1    11-11-2011  amloessb  Added check for non-numeric interval
  22. 'v1.0    11-09-2011  amloessb  First working version
  23.  
  24. Option Explicit
  25.  
  26. Dim objFSO, objSource, objDest, objChildren, objFiles, objDestFile, args
  27. Dim strSource, strDest, strDestFile, strFilename, strChoice, strAnswer, strHeader
  28. Dim subfolder, file, strDestFolder, objDestFolder, strNewFileList, strSize, strName
  29. Dim dateSrcModified, dateDestModified, dateModified
  30. Dim badAnswer, newFiles, isFileOp
  31. Dim objSubFol, objSubFiles, oSrc, oDest
  32. Dim intInterval
  33. Dim DTab, TTab
  34.  
  35. 'ynAnswer ()
  36. 'Purpose: Reads in an answer from StdIn, and loops if it is not "y" or "n"
  37. '         The case of the user's answer does not matter.
  38. 'Returns: the answer "y" or "n"
  39. Function ynAnswer ()
  40.     badAnswer = True
  41.     While badAnswer
  42.         WScript.StdIn.Read(0)
  43.         strChoice = WScript.StdIn.ReadLine()
  44.         If Lcase(strChoice) = "n" Then
  45.             ynAnswer = "n"
  46.             badAnswer = False
  47.         ElseIf Lcase(strChoice) = "y" Then
  48.             ynAnswer = "y"
  49.             badAnswer = False
  50.         Else
  51.             WScript.StdOut.Write "Please answer y or n > "
  52.         End If
  53.     WEnd
  54. End Function
  55.  
  56. 'confirmOp (src, dest, fileOp)
  57. 'Purpose: Asks the user to confirm the backup settings
  58. 'Returns: N/A
  59. 'Depends on ynAnswer
  60. Function confirmOp (src, dest, fileOp)
  61.     WScript.StdOut.Write "The script will now backup "
  62.     If Not fileOp Then
  63.         WScript.StdOut.Write "the contents of" & VBCrLf
  64.     Else
  65.         WScript.StdOut.Write VBCrLf
  66.     End If
  67.     WScript.Echo src
  68.     WScript.Echo "to"
  69.     WScript.Echo dest
  70.     WScript.Echo ""
  71.     WScript.StdOut.Write "Is this correct? [y/n] > "
  72.     strAnswer = ynAnswer()
  73.     If strAnswer = "n" Then
  74.         WScript.Quit 0
  75.     End If
  76. End Function
  77.  
  78. 'printCopyInfo (src)
  79. 'Purpose: Prints the time, name, and size of the given file or folder
  80. 'Returns: N/A
  81. Function printCopyInfo (src)
  82.     dateModified = src.DateLastModified
  83.     strSize = FormatNumber((src.Size / 1024.0), 2)
  84.     strName = src.Name
  85.     'WScript.StdOut.Write VBCrLf
  86.    WScript.Echo dateModified & VBTab & strName & VBTab & strSize & "K"
  87. End Function
  88.  
  89. 'compareDateModified (strSrc, strDest, strMsg)
  90. 'Purpose: Appends the file information to strMsg if the dest file is newer
  91. 'Returns: strMsg, with the file's entry appended if the dest file is newer
  92. Function compareDateModified (strSrc, strDest, strMsg)
  93.     If objFSO.FileExists(strDest) Then
  94.         Set oDest = objFSO.GetFile(strDest)
  95.         Set oSrc = objFSO.GetFile(objFSO.BuildPath(strSrc,oDest.Name))
  96.         dateSrcModified = oSrc.DateLastModified
  97.         dateDestModified = oDest.DateLastModified
  98.         If dateDestModified > dateSrcModified Then
  99.             compareDateModified = strMsg & oSrc.Name & DTab & dateSrcModified & _
  100.                                   DTab & dateDestModified & VBCrLf
  101.         End If
  102.     End If
  103. End Function
  104.  
  105. 'folderCompareDateModified (strSrc, strDest, strMsg)
  106. 'Purpose: Recursive compareDateModified, by folder
  107. 'Returns: strMsg, appended to as necessary
  108. 'Depends on compareDateModified
  109. Function folderCompareDateModified (strSrc, strDest, strMsg)
  110.     If objFSO.FolderExists(strDest) Then
  111.         Set oSrc = objFSO.GetFolder(strSrc)
  112.         Set oDest = objFSO.GetFolder(strDest)
  113.         For Each file In oSrc.Files
  114.             strMsg = compareDateModified(strSrc, objFSO.BuildPath(strDestFolder, file.Name), strMsg)
  115.         Next
  116.         For Each subfolder In objFSO.GetFolder(strSrc).SubFolders
  117.             strDestFolder = objFSO.BuildPath(strDest, subfolder.Name)
  118.             strMsg = folderCompareDateModified (subfolder.Path, objFSO.BuildPath(strDestFolder, subfolder.Name), strMsg)
  119.         Next
  120.     End If
  121.     folderCompareDateModified = strMsg
  122. End Function
  123.  
  124. 'compareAndCopy (oSrc, oDest, dest)
  125. 'Purpose: Copies oSrc to dest if oSrc is newer. 'dest' is the folder that oSrc
  126. '         will be copied into, while oDest is the file/folder that oSrc will be
  127. '         replacing.
  128. 'Returns: N/A
  129. Function compareAndCopy (oSrc, oDest, dest)
  130.     'Failsafe (source and destination names must match)
  131.    If Not oSrc.Name = oDest.Name Then
  132.         WScript.Echo "FAIL: " & oSrc.Name & " != " & oDest.Name
  133.         WScript.Quit 2
  134.     End If
  135.     dateSrcModified = oSrc.DateLastModified
  136.     dateDestModified = oDest.DateLastModified
  137.     If dateSrcModified > dateDestModified Or Not oSrc.Size = oDest.Size Then
  138.         oSrc.Copy dest, True
  139.         Call printCopyInfo(oSrc)
  140.     Else
  141.         'WScript.StdOut.Write "."
  142.    End If
  143. End Function
  144.  
  145. 'folderCompareAndCopy (oSrc, oDest, dest)
  146. 'Purpose: Recursive compareAndCopy, by folder
  147. 'Returns: N/A
  148. 'Depends on compareAndCopy
  149. Function folderCompareAndCopy (oSrc, oDest, dest)
  150.     'Failsafe (source and destination names must match)
  151.    If Not oSrc.Name = oDest.Name Then
  152.         WScript.Echo "FAIL: " & oSrc.Name & " != " & oDest.Name
  153.         WScript.Quit 2
  154.     End If
  155.     Set objSubFol = oSrc.SubFolders
  156.     Set objSubFiles = oSrc.Files
  157.     'Recursion end case: individual files
  158.    For Each file In objSubFiles
  159.         strDestFolder = oDest.Path
  160.         strDestFolder = fixFolderStr(strDestFolder)
  161.         strDestFile = objFSO.BuildPath(oDest.Path, file.Name)
  162.         If Not objFSO.FileExists(strDestFile) Then
  163.             objFSO.CreateTextFile strDestFile
  164.         End If
  165.         Set objDestFile = objFSO.GetFile(strDestFile)
  166.         Call compareAndCopy(file, objDestFile, strDestFolder)
  167.     Next
  168.     'Recurse through all subfolders
  169.    For Each subfolder In objSubFol
  170.         strDestFolder = objFSO.BuildPath(oDest.Path, subfolder.Name)
  171.         If Not objFSO.FolderExists(strDestFolder) Then
  172.             objFSO.CreateFolder(strDestFolder)
  173.         End If
  174.         Set objDestFolder = objFSO.GetFolder(strDestFolder)
  175.         Call folderCompareAndCopy(subfolder, objDestFolder, oDest.Path)
  176.     Next
  177. End Function
  178.  
  179. 'fixFolderStr (folder)
  180. 'Purpose: Put a trailing \ on the folder path if it's missing
  181. 'Returns: The correctrd path string
  182. Function fixFolderStr (folder)
  183.     If Not Mid(folder,Len(folder),1) = "\" Then
  184.         fixFolderStr = folder & "\"
  185.     Else
  186.         fixFolderStr = folder
  187.     End If
  188. End Function
  189.  
  190. '---MAIN FUNCTION START---
  191.  
  192. Set args = WScript.Arguments
  193. DTab = VBTab & VBTab
  194. TTab = VBTab & VBTab & VBTab
  195. badAnswer = True
  196. newFiles = False
  197. strHeader = "Name" & TTab & "Source Date"& TTab & "Destination Date"
  198. strNewFileList = ""
  199. intInterval = 5
  200.  
  201. 'Print the usage statement
  202. If Not (WScript.Arguments.Count = 2 Or WScript.Arguments.Count = 3) Then
  203.     WScript.Echo ""
  204.     WScript.Echo "Usage: cscript liveBackup.vbs <source> <destination> [interval]"
  205.     WScript.Echo ""
  206.     WScript.Echo "Checks the source every {interval} seconds for changes, and copies changed"
  207.     WScript.Echo "files to the destination.  Folder hierarchies are preserved."
  208.     WScript.Echo ""
  209.     WScript.Echo "Arguments:"
  210.     WScript.Echo "source      - the source directory or file to be backed up"
  211.     WScript.Echo "destination - the destination directory where the backup will be saved"
  212.     WScript.Echo "interval    - the frequency (in seconds) at which the script will check"
  213.     WScript.Echo "              for changes in the source (default: 5)"
  214.     WScript.Quit 1
  215. End If
  216.  
  217. strSource = args(0)
  218. strDest = args(1)
  219.  
  220. If WScript.Arguments.Count = 3 Then
  221.     If IsNumeric(args(2)) Then
  222.         intInterval = args(2)
  223.     Else
  224.         WScript.Echo "The supplied interval is not a number."
  225.         WScript.Echo "Using the default interval of 5 seconds."
  226.     End If
  227. End If
  228.  
  229. Set objFSO = CreateObject("Scripting.FileSystemObject")
  230.  
  231. If objFSO.FolderExists(strDest) Then
  232.     Set objDest = objFSO.GetFolder(strDest)
  233.     If objFSO.FolderExists(strSource) Then
  234.         'Directory backup mode
  235.        isFileOp = False
  236.         Set objDest = objFSO.GetFolder(strDest)
  237.         Set objSource = objFSO.GetFolder(strSource)
  238.         Set objChildren = objSource.SubFolders
  239.         Set objFiles = objSource.Files
  240.         'Check for new folders in the destination
  241.        For Each subfolder In objChildren
  242.             strDestFolder = objFSO.BuildPath(strDest, subfolder.Name)
  243.             strNewFileList = folderCompareDateModified (subfolder.Path, strDestFolder, strNewFileList)
  244.         Next
  245.         'Check for new files in the destination
  246.        For Each file In objFiles
  247.             strDestFile = objFSO.BuildPath(strDest, file.Name)
  248.             strNewFileList = compareDateModified (strSource, strDestFile, strNewFileList)
  249.         Next
  250.         'If there are newer folders/files in the dest, print list
  251.        If Not strNewFileList = "" Then
  252.             WScript.Echo strHeader
  253.             WScript.Echo strNewFileList
  254.             WScript.Echo "The above files are newer at the destination then at the source."
  255.             WScript.Echo "You will lose any changes you have made to the destination files"
  256.             WScript.Echo "if you choose to continue."
  257.             WScript.Echo ""
  258.             WScript.StdOut.Write "Would you like to continue anyway? [y/n] > "
  259.             strAnswer = ynAnswer()
  260.             If strAnswer = "n" Then
  261.                 WScript.Quit 0
  262.             End If
  263.         End If
  264.         'Put a trailing \ on the destination path if it's missing
  265.        strDest = fixFolderStr(strDest)
  266.         'Confirm the operation
  267.        Call confirmOp(strSource, strDest, isFileOp)
  268.         'Do the initial copy
  269.        For Each subfolder In objChildren
  270.             subfolder.Copy strDest, True
  271.         Next
  272.         For Each file In objFiles
  273.             file.Copy strDest, True
  274.         Next
  275.         WScript.Echo "The script is now actively backing up your files."
  276.         WScript.Echo "Press ^C to stop."
  277.         'MAIN BACKUP LOOP (directory mode)
  278.        While True
  279.             For Each subfolder In objChildren
  280.                 strDestFolder = objFSO.BuildPath(strDest, subfolder.Name)
  281.                 If Not objFSO.FolderExists(strDestFolder) Then
  282.                     objFSO.CreateFolder(strDestFolder)
  283.                 End If
  284.                 Set objDestFolder = objFSO.GetFolder(strDestFolder)
  285.                 Call folderCompareAndCopy(subfolder, objDestFolder, strDest)
  286.             Next
  287.             For Each file In objFiles
  288.                 strDestFile = objFSO.BuildPath(strDest, file.Name)
  289.                 If Not objFSO.FileExists(strDestFile) Then
  290.                     objFSO.CreateTextFile strDestFile
  291.                 End If
  292.                 Set objDestFile = objFSO.GetFile(strDestFile)
  293.                 Call compareAndCopy(file, objDestFile, strDest)
  294.             Next
  295.             'WScript.StdOut.Write "."
  296.            WScript.Sleep(1000 * intInterval)
  297.         WEnd
  298.        
  299.     ElseIf objFSO.FileExists(strSource) Then
  300.         'File backup mode
  301.        isFileOp = True
  302.         Set objSource = objFSO.GetFile(strSource)
  303.         strFilename = objSource.Name
  304.         strDestFile = objFSO.BuildPath(strDest, strFilename)
  305.         'Check for a newer file in the destination
  306.        strNewFileList = compareDateModified (strSource, strDestFile, strNewFileList)
  307.         If Not strNewFileList = "" Then
  308.             'Destination file is newer than the source
  309.            WScript.Echo strHeader
  310.             WScript.Echo strNewFileList
  311.             WScript.Echo "The above files are newer at the destination then at the source."
  312.             WScript.Echo "You will lose any changes you have made to the destination files"
  313.             WScript.Echo "if you choose to continue."
  314.             WScript.Echo ""
  315.             WScript.StdOut.Write "Would you like to continue anyway? [y/n] > "
  316.             strAnswer = ynAnswer()
  317.             If strAnswer = "n" Then
  318.                 WScript.Quit 0
  319.             End If
  320.         End If
  321.         'Put a trailing \ on the destination path if it's missing
  322.        strDest = fixFolderStr(strDest)
  323.         'Confirm the operation
  324.        Call confirmOp(strSource, strDest, isFileOp)
  325.         'Do the initial copy
  326.        objSource.Copy strDest, True
  327.         Set objDestFile = objFSO.GetFile(strDestFile)
  328.         WScript.Echo "The script is now actively backing up your files."
  329.         WScript.Echo "Press ^C to stop."
  330.         'MAIN BACKUP LOOP (file mode)
  331.        While True
  332.             Call compareAndCopy(objSource, objDestFile, strDest)
  333.             'WScript.StdOut.Write "."
  334.            WScript.Sleep(1000 * intInterval)
  335.         WEnd
  336.     End If
  337. Else
  338.     WScript.Echo "The destination directory does not exist or is not a directory."
  339.     WScript.Echo strDest
  340.     WScript.Quit 1
  341. End If
Add Comment
Please, Sign In to add comment