amloessb

liveBackup.vbs (v1.1)

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