'********************************************************************** ' sync.vbs ' ' This script makes a "synchronised" backup of a folder tree from one ' path to another. ' ' Extraneous directories (folders) may be removed from the destination ' tree by specifying the /RD switch on the command line. These are ' directories already existing in the destination tree but no longer ' found in the source tree. ' ' Extraneous files may be removed from the destination tree by specifying ' the /RF switch on the command line. These are files which exist in ' destination directories but not in source directories. ' ' Both extraneous directories and files can be removed by specifying the ' /C switch on the command line. This switch is equivalent to specifying ' both the /RD and /RF switches ' ' Usage: sync.vbs ' or: cscript /nologo sync.vbs ' or: wscript /nologo sync.vbs ' ' Notes: Paths can use drive letters or UNC specifications. ' '********************************************************************** Dim oArgs Dim TempArg Dim bRemoveFolders Dim bRemoveFiles Dim SleepTime Dim SrcFolder Dim arrSrcFolders() Dim s Dim DstFolder Dim arrDstFolders() Dim d Dim arrCopyFrom() Dim arrCopyTo() Dim arrSizes() Dim fMax Dim TotalSize Dim oExplorer Dim FSO On Error Resume Next bRemoveFolders = False bRemoveFiles = False SleepTime = 10 ' default to leaving display onscreen for 10 seconds Set oArgs = WScript.Arguments For s = 0 To oArgs.Count - 1 TempArg = Ucase(Left(oArgs(s),3)) Select Case TempArg Case "/?" ShowSyntax() Wscript.Quit Case "/S:" SrcFolder = Trim(Mid(oArgs(s),4)) Case "/D:" DstFolder = Trim(Mid(oArgs(s),4)) Case "/RD" bRemoveFolders = True Case "/RF" bRemoveFiles = True Case "/C" bRemoveFiles = True bRemoveFolders = True Case "/T:" SleepTime = Cint(Mid(oArgs(s),4)) If SleepTime < 0 Then SleepTime = 0 End If Case Else If Left(oArgs(s),1) <> "/" Then If SrcFolder = "" Then SrcFolder = oArgs(s) ElseIf DstFolder = "" Then DstFolder = oArgs(s) Else Wscript.Echo "Unknown parameter on command line... " & oArgs(s) ShowSyntax() Wscript.Quit End If End If End Select Next If SrcFolder = "" or DstFolder = "" Then Wscript.Echo "You must enter a 'SourcePath' and 'DestinationPath' when starting this script." ShowSyntax() Wscript.Quit End If If Right(SrcFolder,1) <> "\" Then SrcFolder = SrcFolder & "\" End If If Right(DstFolder,1) <> "\" Then DstFolder = DstFolder & "\" End If If InStr(LCase(SrcFolder),LCase(DstFolder)) > 0 _ Or InStr(LCase(DstFolder),LCase(SrcFolder)) > 0 Then Wscript.Echo "The 'SourcePath' and 'DestinationPath' cannot overlap!" Wscript.Quit End If TotalSize = 0 Set FSO = CreateObject("Scripting.FileSystemObject") Set oExplorer = CreateObject("InternetExplorer.Application") oExplorer.Navigate2 "about:blank" oExplorer.Width = 550 oExplorer.Height = 300 oExplorer.Top = 300 oExplorer.Left = 300 oExplorer.Toolbar = False oExplorer.Menubar = False oExplorer.Statusbar = False oExplorer.Visible = True oExplorer.Document.Write "" oExplorer.Document.Write "

File Backup in Progress

" oExplorer.Document.Write "

Beginning backup...
" oExplorer.Document.Title = "Please be patient.... " GetSrcInfo GetDstInfo CreateMissingFolders If bRemoveFolders Then DeleteExtraFolders End If If bRemoveFiles Then DeleteExtraFiles End If FindFilesNeedingBackup CopySourceToDest oExplorer.document.write "" oExplorer.Document.Write " Finished!
" If SleepTime > 0 Then Wscript.Sleep (SleepTime * 1000) End If QuitScript() Sub GetSrcInfo() oExplorer.Document.Write "Analyzing source directories...
" '-- get information about source directories If FSO.FolderExists(SrcFolder) Then ReDim arrSrcFolders(100) s = 0 arrSrcFolders(0) = Left(SrcFolder, Len(SrcFolder) - 1) GetSrcFolders FSO.GetFolder(SrcFolder) ReDim Preserve arrSrcFolders(s) Else Wscript.Echo "Source folder not found... aborting." QuitScript() End If End Sub Sub GetSrcFolders(Folder) Dim Subfolder For Each Subfolder In Folder.SubFolders s = s + 1 If s > Ubound(arrSrcFolders) Then ReDim Preserve arrSrcFolders(Ubound(arrSrcFolders) + 100) End If arrSrcFolders(s) = SubFolder.Path GetSrcFolders Subfolder Next End Sub Sub GetDstInfo() oExplorer.Document.Write "Analyzing backup directories...
" '-- get information about destination directories If Not FSO.FolderExists(DstFolder) Then CreateMultiLevelFolder DstFolder End If ReDim arrDstFolders(100) d = 0 arrDstFolders(0) = Left(DstFolder, Len(DstFolder) - 1) GetDstFolders FSO.GetFolder(DstFolder) ReDim Preserve arrDstFolders(d) End Sub Sub CreateMultiLevelFolder(FolderPath) Dim TempPath Dim Path Dim arrNodes Dim n TempPath = FolderPath Path = "" ' See if input is in UNC format... If Instr(TempPath,"\\") > 0 Then TempPath = Mid(TempPath,3) n = Instr(TempPath,"\") Path = "\\" & Left(TempPath,n) TempPath = Mid(TempPath,n+1) End If arrNodes = Split(TempPath,"\") Path = Path & arrNodes(0) For n = 1 To UBound(arrNodes) Path = Path & "\" & arrNodes(n) If Not FSO.FolderExists(Path) Then FSO.CreateFolder(Path) End If Next End Sub Sub GetDstFolders(Folder) Dim Subfolder For Each Subfolder In Folder.SubFolders d = d + 1 If d > Ubound(arrDstFolders) Then ReDim Preserve arrDstFolders(Ubound(arrDstFolders) + 100) End If arrDstFolders(d) = SubFolder.Path GetDstFolders Subfolder Next End Sub Sub CreateMissingFolders() Dim LenOfSrcBaseDir Dim strFolder, f oExplorer.Document.Write "Creating any missing backup directories...
" LenOfSrcBaseDir = Len(SrcFolder) + 1 For f = 0 to s strFolder = DstFolder & Mid(arrSrcFolders(f), LenOfSrcBaseDir) If Not FSO.FolderExists(strFolder) Then FSO.CreateFolder(strFolder) End IF Next End Sub Sub DeleteExtraFolders() Dim LenOfDstBaseDir Dim strFolder, f oExplorer.Document.Write "Removing any extra backup directories...
" LenOfDstBaseDir = Len(DstFolder) + 1 For f = 0 To d strFolder = SrcFolder & Mid(arrDstFolders(f), LenOfDstBaseDir) If (Not FSO.FolderExists(strFolder)) Then FSO.DeleteFolder arrDstFolders(f),True End IF Next End Sub Sub DeleteExtraFiles() Dim LenOfSrcBaseDir Dim LenOfDstBaseDir Dim strDstFolder Dim strDstFile Dim strSrcFile Dim oFldr, oFile Dim fc, f oExplorer.Document.Write "Removing any extra backup files...
" LenOfSrcBaseDir = Len(SrcFolder) + 1 LenOfDstBaseDir = Len(DstFolder) + 1 For f = 0 to s strDstFolder = DstFolder & Mid(arrSrcFolders(f), LenOfSrcBaseDir) set fc = FSO.GetFolder(strDstFolder).Files For Each oFile In fc strDstFile = strDstFolder & IIf(f = 0, "", "\") & oFile.Name strSrcFile = SrcFolder & Mid(strDstFile, LenOfDstBaseDir) If (Not FSO.FileExists(strSrcFile)) And FSO.FileExists(strDstFile) Then FSO.DeleteFile strDstFile,True End If Next Next Set fc = Nothing End Sub Sub FindFilesNeedingBackup() Dim LenOfSrcBaseDir Dim strFrom Dim strTo, f, fc, oFile oExplorer.Document.Write "Determining which files to backup...
" ReDim arrCopyFrom(100) ReDim arrCopyTo(100) ReDim arrSizes(100) fMax = -1 LenOfSrcBaseDir = Len(SrcFolder) + 1 arrSrcFolders(0) = SrcFolder arrDstFolders(0) = DstFolder For f = 0 To s Set fc = FSO.GetFolder(arrSrcFolders(f)).Files For Each oFile In fc strFrom = arrSrcFolders(f) & "\" & oFile.Name strTo = DstFolder & Mid(strFrom, LenOfSrcBaseDir) If Not FSO.FileExists(strTo) Then AddToList strFrom, strTo, oFile.Size Else Set oDstFile = FSO.GetFile(strTo) If FileIsNewer(oFile, oDstFile) Then AddToList strFrom, strTo, oFile.Size End If End If Next Next Set fc = Nothing End Sub Function FileIsNewer(Source, Dest) FileIsNewer = False If Source.DateLastModified > Dest.DateLastModified Then FileIsNewer = True End If End Function Sub AddToList(strFrom, strTo, FileSize) Dim fCur fCur = Ubound(arrCopyFrom) fMax = fMax + 1 if fMax > fCur Then ReDim Preserve arrCopyFrom(fCur + 100) ReDim Preserve arrCopyTo(fCur + 100) ReDim Preserve arrSizes(fCur + 100) End If arrCopyFrom(fMax) = strFrom arrCopyTo(fMax) = strTo arrSizes(fMax) = FileSize TotalSize = TotalSize + FileSize End Sub Sub CopySourceToDest() Dim CurPercent, TotalCopied, myProgressIndicator, f TotalCopied = 0 If fMax > -1 Then If fMax = 0 Then oExplorer.Document.Write "Backing up 1 file...
" Else oExplorer.Document.Write "Backing up " & fMax + 1 & " files...
" End If oexplorer.document.write "

" Set myProgressIndicator = oExplorer.Document.All("ProgressIndicator") For f = 0 To fMax If FSO.FileExists(arrCopyTo(f)) Then FSO.DeleteFile arrCopyTo(f), True End If FSO.CopyFile arrCopyFrom(f), arrCopyTo(f) TotalCopied = TotalCopied + arrSizes(f) CurPercent = CStr(Round(100 * TotalCopied / TotalSize)) & "%" ' Set the current progress indicator myProgressIndicator.innerHTML = CurPercent myProgressIndicator.style.width = CurPercent Next Else oExplorer.Document.Write "No files need to be backed up...
" End If End Sub Function IIf( expr, truepart, falsepart ) If expr Then IIf = truepart Else IIf = falsepart End If End Function Sub QuitScript() oExplorer.Quit Set oExplorer = Nothing Set FSO = Nothing Wscript.Quit End Sub Sub ShowSyntax() Wscript.Echo "Sync.vbs [/S:] [/D:] [/RD] [/RF] [/C] [/T:] " Wscript.Echo " " Wscript.Echo " All switches are case insensitive as well as 'order insensitive'. Directory " Wscript.Echo " names with embedded spaces are supported either with or without surrounding " Wscript.Echo " quotes (single or double), however, if they contain multiple adjacent spaces " Wscript.Echo " they must be quoted. Spaces after the ':' are ignored. " Wscript.Echo " " Wscript.Echo " /RD specifies to remove extraneous directories (folders) from the " Wscript.Echo " destination path if found. " Wscript.Echo " " Wscript.Echo " /RF specifies to remove extraneous files from the destination path if found. " Wscript.Echo " " Wscript.Echo " /C Equivalent to specifying /RD and /RF on the command line. " Wscript.Echo " " Wscript.Echo " /T: Optional switch to specify number of seconds to leave final " Wscript.Echo " screen display visible. Defaults to 10 seconds if not specified. " Wscript.Echo " " Wscript.Echo " The /S: and /D: switches are optional. When not used, the first parameter " Wscript.Echo " on the command line not preceded by '/' will be taken as the source path and " Wscript.Echo " the second parameter not preceded by '/' will be taken as the destination " Wscript.Echo " path. " Wscript.Echo " " Wscript.Echo " The use of the '-' character in lieu of '/' is not supported. " Wscript.Echo " " End Sub