Tom's Guide | Tom's Hardware | Tom's Games
![]() |
![]() |
![]() |
I'm trying to create a vb script which will allow me to compare my documents with a backup of my documents on a server. So here is what I need the script to do. Person A logs off at night and his my documents are backed up the server. Person A logs on the next day and deletes several files from my documents as they are no longer needed. The backup program which runs will not detect that and delete the files off his backup on the server.
Ideally I want this script to run when the person logs on. It will then compare what is in his my documents to what is in the backups. If Person A has deleted files, then it will delete those same files off the server. I found a script already online, and I've tried tweaking it but when I run it, nothing changes, and it doesn't give me any errors. Here it is so far:
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objNetwork = wscript.CreateObject("wscript.network")SOURCE_FOLDER = "C:\Documents and Settings\dazra\My Documents\"
DESTINATION_FOLDER = "F:\xpbackup\documents and settings\dazra\My Documents\"
ReplicateFolders objFSO, SOURCE_FOLDER, DESTINATION_FOLDER'******************
' Sub ReplicateFolders
'
' This procedure replicates between the source and the destination
' directories at the folder level. A recursive search is done
' between the 2 directories and folders compared. If a folder exists on the
' destination but not on the source, the source is deleted
'******************Sub ReplicateFolders (objFSO, strSourceFolderPath, strDestinationFolderPath)
Dim aFolderArraySource ' Declares an array for folder source
Dim aFolderArrayDestination ' Declares an array for folder destination
Dim FolderListSource ' declares a var for folder list source
Dim FolderListDestination ' declares a var for folder list destination
Dim oFolderSource
Dim oFolderDestination
Dim bSourceExists
Dim bDestinationExistsOn Error Resume Next
Set aFolderArraySource = objFSO.GetFolder(strSourcefolderpath)
Set aFolderArrayDestination = objFSO.GetFolder(strDestinationfolderpath)
Set FolderListSource = aFolderArraySource.SubFolders
Set FolderListDestination = aFolderArrayDestination.SubFoldersReplicateFiles objFSO, strSourcefolderpath, strDestinationfolderpath
For Each oFolderDestination in FolderListDestination
bSourceExists = 0
For each oFolderSource in FolderListSource
If oFolderDestination.Name = oFolderSource.Name then
bSourceExists = 1
Exit For
End If
Next
If bSourceExists = 0 then
objFSO.DeleteFolder strDestinationfolderpath & "\" & _
oFolderDestination.Name, true
End if
NextEnd Sub
'******************
' Sub ReplicateFiles
'
' This procedure replicates between the source and the destination
' directories at the file level.
' If a particular file on the destination directory
' does not exist on the source at any level then the destination file
' is removed from the destination directory.
'
'******************
Sub ReplicateFiles (objFSO, strSourcefolderpath, strDestinationfolderpath)
Dim aFileArraySource
Dim aFileArrayDestination
Dim FileListSource
Dim FileListDestination
Dim oFileSource
Dim oFileDestination
Dim bSourceExists
Dim bDestinationExistsOn Error Resume Next
For each oFileDestination in FileListDestination
bSourceExists = 0
For each oFileSource in FileListSource
If oFileDestination.Name = oFileSource.Name then
If oFileDestination.DateLastModified = oFileSource.DateLastModified then
bSourceExists = 1
Exit For
End If
End If
Next
If bSourceExists = 0 then
objFSO.DeleteFile strDestinationfolderpath & "\" & _
oFileDestination.Name,true
End If
NextEnd Sub
Help me plz! THANKS!

I could take the time to go through that code and make any necessary changes, but why are you making this more difficult than it needs to be?
Instead of creating a second process to remove deleted files from the backup, why not just do it during the backup process? I don't know what you are using at the moment to do the "backup", but there are many good freeware scripts/programs that will replicate deletions as well. Here is one: http://www.karenware.com/powertools/ptreplicator.asp
One last note. The purpose of a backup is to restore files which have become lost or corrupted - this includes accidental deletions! By replicating the users deletions you may be deleting a file which the user unintentionally deleted and needs to recover. You might want to consider using a backup method that allows youto restore older files. You could create 7 different backup folders, one for each day of the week so that you can restore anything back to 7 days. A weekly and monthly backup would be an option too. Just a suggestion.
Michael J

I was using a batch file to do a backup, and I'm currently exploring how to do a replication with another batch file as well as vbs. I have little knowledge on batch files but an ok amount on vbs. I will look into that link and see what it has to offer, but being that this is for a company, unauthorized programs are not "allowed". I will still look into it.
Thanks

I just looked over the link you sent, and spoke with my manager on it, and that does not look like it will be the best way to go about it. It wouldn't be allowed to install that on all workstations.
The best way for us atm is to come up with a script/batch file so that we can use windows gpedit to have it run during startup/shutdown.
If anyone can help me on the coding i'd appreciate it.
Thanks

OK, I lied. I was bored and ddecided to take a look at the code. It worked for folders but not for files. To make it work for file too add the line in blue below:
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objNetwork = wscript.CreateObject("wscript.network")SOURCE_FOLDER = "C:\test_src\"
DESTINATION_FOLDER = "C:\test_dst\"
ReplicateFolders objFSO, SOURCE_FOLDER, DESTINATION_FOLDER'******************
' Sub ReplicateFolders
'
' This procedure replicates between the source and the destination
' directories at the folder level. A recursive search is done
' between the 2 directories and folders compared. If a folder exists on the
' destination but not on the source, the source is deleted
'******************Sub ReplicateFolders (objFSO, strSourceFolderPath, strDestinationFolderPath)
Dim aFolderArraySource ' Declares an array for folder source
Dim aFolderArrayDestination ' Declares an array for folder destination
Dim FolderListSource ' declares a var for folder list source
Dim FolderListDestination ' declares a var for folder list destination
Dim oFolderSource
Dim oFolderDestination
Dim bSourceExists
Dim bDestinationExistsOn Error Resume Next
Set aFolderArraySource = objFSO.GetFolder(strSourcefolderpath)
Set aFolderArrayDestination = objFSO.GetFolder(strDestinationfolderpath)
Set FolderListSource = aFolderArraySource.SubFolders
Set FolderListDestination = aFolderArrayDestination.SubFoldersReplicateFiles objFSO, strSourcefolderpath, strDestinationfolderpath
For Each oFolderDestination in FolderListDestination
bSourceExists = 0
For each oFolderSource in FolderListSource
If oFolderDestination.Name = oFolderSource.Name then
bSourceExists = 1
Exit For
End If
Next
If bSourceExists = 0 then
objFSO.DeleteFolder strDestinationfolderpath & "\" & _
oFolderDestination.Name, true
End if
NextEnd Sub
'******************
' Sub ReplicateFiles
'
' This procedure replicates between the source and the destination
' directories at the file level.
' If a particular file on the destination directory
' does not exist on the source at any level then the destination file
' is removed from the destination directory.
'
'******************
Sub ReplicateFiles (objFSO, strSourcefolderpath, strDestinationfolderpath)
Dim aFileArraySource
Dim aFileArrayDestination
Dim FileListSource
Dim FileListDestination
Dim oFileSource
Dim oFileDestination
Dim bSourceExists
Dim bDestinationExistsOn Error Resume Next
Set aFileArraySource = objFSO.GetFolder(strSourcefolderpath)
Set aFileArrayDestination = objFSO.GetFolder(strDestinationfolderpath)
Set FileListSource = aFileArraySource.files
Set FileListDestination = aFileArrayDestination.filesFor each oFileDestination in FileListDestination
bSourceExists = 0
For each oFileSource in FileListSource
If oFileDestination.Name = oFileSource.Name then
If oFileDestination.DateLastModified = oFileSource.DateLastModified then
bSourceExists = 1
Exit For
End If
End If
Next
If bSourceExists = 0 then
MsgBox strDestinationfolderpath & "\" & oFileDestination.Name
objFSO.DeleteFile strDestinationfolderpath & "\" & _
oFileDestination.Name,true
End If
NextEnd Sub
'******* END SCRIPT *******
Also one of the comments in the script states: "If a particular file on the destination directory does not exist on the source at any level then the destination file is removed from the destination directory." That is not true. It only deletes the file if it does not exist in the same directory.Michael J

I see my error and am smacking my head. Sometimes you just need a second set of eyes. Thanks for the help.

my other question was this... if i wanted to put a universal variable in the place of username, so isntaed of
SOURCE_FOLDER = "C:\Documents and Settings\dazra\My Documents\"I change it to SOURCE_FOLDER = "C:\Documents and Settings\" & objectNetwork.UserName &" \My Documents\"
Am I correct in saying that?

I don't see why not. I always like to use lots of MsgBox's to see what is going on in my code when writing it. So do this:
MsgBox "C:\Documents and Settings\" & objectNetwork.UserName &" \My Documents\"
Does it give the correct path?
Also, I found the original script you referenced above here. It includes the abilty to copy new files and folders to the destination as well as removing deleted files & folders from the destination. Seems like you could do everything at one time instead of having two different scripts.
Michael J

Thats exactly where I got the script from. The only problem is that copies the entire contents of my documents over. In our current batch file I exclude certain files/folders, so I thought it would be easier to just remove certain lines of code from that one rather than tweak it to exclude certain files/folders.

For some reason that script isn't working. I double click the script and it just doesn't do anything.
Interesting.

never mind, I figured out why. The destination_source didn't exist so it didn't run. I should try and make an if not destination_source.exist then create

Is there a way in vbs to exclude certain file extensions and or folders? For example if I don't want to include any .mp3, .exe, .wmv etc, what command what I use for that?

It would also be pretty simple to create an exclusion list of folders not to copy:
====Include this at the top=======
'Include the paths of excluded folders,
'comma separatedf,rom the root of the source
excludedFolders = "NetHood,PrintHood,Microsoft\AddIns"xFolderArray = Split(excludedFolders, ",", -1, 1)
====== Add this logic into the code ===
====== to skip excluded folders ===
For Each oFolderSource in FolderListSource
skip = false
For Each xFolder in xFolderArray
If strSourcefolderpath & "\" & xFolder =
oFolderSource.Path Then
skip = true
End If
NextIf skip = false Then
...proceed with codeDont forget to add an End If just before the end of the first For loop.
Actually, I'm looking to modify this code for my personal use on my home network.
Michael J

I posted before reading your last message. Excluding files by extentsion would be similar. Create an exclusion list of extensions
excludedFiles = ".mp3,.exe,.wmv"
xFileArray = Split(excludedFiles, ",", -1, 1)Then add logic into the code to check the file before copying it.
However, I would probably use the xcopy command within the vbscript to do the copying since it would probably be more efficient and it already has exclusion capabilities built in.
Michael J

Another question.... When testing this script I found that it will do the following: if you have my documents\folderA\folder1 and you delete folder 1 it will not replicate it. If you delete FolderA then it will replicate successfully. Any thoughts on this?

Yes, the script you are using ONLY goes through the subfolders in the root of the source. If one is missing it replicates it. Then it ONLY goes through the files in those first set of subfolders and replicates them if missing. The script is not recursive (even though the comments say it is). It should check the first folder in the source, then check the subfolders of that folder, and then all the sobfolders of those and so on BEFORE it goes to the 2nd subfolder in the source root.
The current script will need a bit of rewriting in order to handle sub folders properly. But, here is a link to a tutorial which shows an easy way to write a script to recursively go through sub folders (see the section on searching through file system): Using VBScript and the FileSystemObject to Replace Batch Files
Michael J

objCurrentFolder is a folder object, same as when the current script uses this:
Set aFolderArraySource = objFSO.GetFolder
Once you have a folder as an object, there are a lot of procedures (not sure if this is the right terminology) you can do with it. By appending the .Files to the end of it you are referencing all of the files in that folder as an array. You could also use .Name (to get the name of the folder), .Path (to get the path of the folder), and more: modified date, creation date, etc, etc.
By using:
For Each objFile In objCurrentFolder.Files
...statements to run
Next
You are creating a loop which will assign each file in the folder as an object to objFile. You can then perform whatever functions you want on that file object: get properties such as name, path, size or perform operations such as copy and move.
Michael J

I'm back with another question. Sorry for the delay but stuff came up that had to be done and this got put on hold.
It seems all I have to do is change this:
For Each oFolderDestination in FolderListDestination
bSourceExists = 0To This
For Each oFolderDestination in FolderListDestination.files
bSourceExists = 0and add this as well
For Each objNewFolder In oFolderDestination.subFolders
CheckFolder objNewFolder, objLogFile
NextDoes that seem right? Only reason I ask is cause I don't want to test and end up deleting data.

"To This
For Each oFolderDestination in FolderListDestination.files
bSourceExists = 0"No, that wouldn't make sense. "FolderListDestination" is an array of folders. The individual folders have files, but the array does not.
"For Each objNewFolder In oFolderDestination.subFolders
CheckFolder objNewFolder, objLogFile
Next"Pretty close. The function we want to call is actually "ReplicateFolders" (unless you have changed it). That function takes three arguments: objFSO, strSourceFolderPath, strDestinationFolderPath. The last two need to be a string, not an object. So it would go something like this:
For Each objNewFolder In oFolderDestination.subFolders
ReplicateFolders objFSO, objNewFolder.Path sourceFolderSubPath
NextThe difficulty here is determining the correct taget path. If you were just dealing with the first level of subfolders (as the original script did) then you would just need the DESTINATION_FOLDER specified in the top plus the sub folder name. Once you go a level deeper, then what.
Here's an example:
SOURCE_FOLDER = "c:myfiles\"
DESTINATION_FOLDER = "d:\archive\"
CURRENT_FOLDER = "c:myfiles\a\"You could then append the destination folder with the current folder name to get "d:\archive\" + "a\" (uou may need to add backslashes as appropriate).
However, if the CURRENT_FOLDER = "c:myfiles\a\b\c\" how do you get the source folder of "d:\archive\a\b\c\". How I would do it would be to take the current path of the current folder and use the RIGHT function to strip away everything up to the first subfolder like this:
NewSourceFolder = DESTINATION_FOLDER & RIGHT(objNewFolder.Path,(Len(objNewFolder.Path)-Len(SOURCE_FOLDER)))
Of course you would have to account for variable scope. Not sure if DESTINATION_FOLDER & SOURCE_FOLDER are within scope (available) in the funciton.
Actually I think this script could use a rewrite. There is some good code here, but some of the logic is flaweed. If I get some time this weekend I'll see what I can do.
Michael J

I agree with you that it is difficult changing the current script to check all files and subfolders. I've started another script and here's what I have so far. It doesn't work but I'm hoping its on the right track
Set objNetwork = wscript.CreateObject("wscript.network")
strSourceFolder = "C:\Documents and Settings\"&objNetwork.Username&"\"
strDestFolder = "F:\xpbackup\documents and settings\"&objNetwork.Username&"\"Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objSourceFolder = objFSO.GetFolder(strSourceFolder)
Set objDestFolder = objFSO.GetFolder(strDestFolder)Set colSourceFiles = objSourceFolder.Files
Set colDestFiles = objDestFolder.Files
SubFoldersSource objFSO, strSourceFolder, strDestFolderSub SubFoldersSource(objFSO, objSourceFolder, objDestFolder)
on error resume next
Set colSourceFolders = objSourceFolder.SubFolders
Set colDestFolders = objDestFolder.SubFolders
SubFilesSource objFSO, colSourceFiles, colDestFilesFor Each objFile In colDestFiles
bSourceExists = 0
If colDestFIles = colSourceFiles then
bSourceExists = 1
Exit ForEnd If
NextIf bSourceExists = 0 then
objFSO.DeleteFolder objDestFolder & "\" & colDestFolders.Name, true
End ifSubFolderSource objFSO, objSourceFolder, objDestFolder
For Each objSubFolder In colDestFolders
Set colSourceFiles = objSubFolder.FilesFor Each objFile In colSourceFiles
NextShowSubFoldersSource objFSO, objSourceFolder, objDestFolder
Next
End Sub
Sub SubFilesSource(objFSO, objSourceFolder, objDestFolder)Set colSourceFiles = objSourceFolder.Files
Set colDestFiles = objDestFolders.Files
For Each objFile In colDestFiles
bSourceExists = 0
If colDestFIles = colSourceFiles then
bSourceExists = 1
Exit ForEnd If
NextIf bSourceExists = 0 then
objFSO.DeleteFile objDestFolder.Path & "\" & colDestFolders.Name, true
End ifFor Each objSubFolder In colFolders
Set colDestFiles = objSubFolder.Files
For Each objFile In colDestFiles
NextSubFoldersDest(objSubFolder)
Next
End Sub

OK, well it looks like we have been duplicating work! I have rewritten the script from the ground up and have a working version located here: http://repeat-offenders.org/backupscript.htm. I think this will work much better than that original script and is more efficient.
Currently the script:
Replication
1. Starts with source folder and if it doesn't exist on the target copies it and all contents there2. If the source folder does exist on the target it checks the files in that folder and copies any missing files or files with later modified dates to the target
3 Recurses through all subfolders (all levels) in the source, repeating steps 1 & 2 for each
Synchronization
4. Starts with target folder and if it does not exist in the source deletes it.5. If the target folder does exist in source it goes through all files in the target folder and deletes them if they do not exist in the source
6. Recurses through all sub folders (all levels) in the target, repeating steps 4 & 5 for each.
Notes:
- The silent switch will suppress dialogs from appearing (only 1 at the moment). Turn it on for testing.- The replicate switch will determine if steps 1-3 are performed
- The synchronize switch determines if steps 4-6 are performed
- Excluded folders and file types have not been built into it yet.
I welcome you to try it out and send me any feedback you have. Pease use the email address in the script for any questions or comments - this thread is pretty long now!
Michael J

Wow. I really appreciate you helping me on this. Yup, this thread has gotten pretty long but I believe many people out there will benefit from it.
I'm going to take your script and edit that furthur to make two versions. One that does both replicates and syncronizes, and one that only syncronizes.
Again I greatly appreciate your help on this.
Thank you very much!

I've modded your script to just do syncronization and here is the code.
Thanks again.
'=======================================================
'
' Script: VBScript Backup & Sync
' Date: 04/14/2006
' Author: Michael J. Damato
' Contact: mjdamato@cox.net
'
' Notes: This is still in developmetn
'=======================================================
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objNetwork = wscript.CreateObject("wscript.network")SOURCE = "C:\Documents and Settings\"&objNetwork.Username&"\"
TARGET = "F:\xpbackup\documents and settings\"&objNetwork.Username&"\"replicate = true
synchronize = true
silent = falseFLDR_EXcLUDE = ""
FILE_EXCLUDE = ""
'Verify if target folder exists
If Not (objFSO.FolderExists(TARGET)) Then
'Do not synchronize, Perform error handling
MsgBox "Target Missing"
'Proceed if synching is on
ElseIf ( synchronize ) Then
syncFolders SOURCE, TARGET
End If'Cleanup variables
Set objFSO = nothing
Set sourceObj = nothing
Set targetObj = nothing
Set targetFileObj = nothing
Set sourceFileObj = nothingIf Not ( silent ) Then
MsgBox "Backup Complete!", 0, "Done"
End If'=======================================================
Sub syncFolders (currentSource, currentTarget)
'=======================================================
'
'======================================================='Check if source folder exists
If Not (objFSO.FolderExists(currentSource)) Then'Delete the current target folder
objFSO.DeleteFolder currentTargetElse
'Create folder object of the currentTarget
Set targetObj = objFSO.GetFolder(currentTarget)'Perform file synching for the currentTarget
syncFiles currentSource, targetObj'Do recursive processing of sub folders
For Each subFolderObj in targetObj.SubFolders
newSource = SOURCE & RIGHT(subFolderObj.Path,(Len(subFolderObj.Path)-Len(TARGET)))
syncFolders newSource, subFolderObj.path
NextEnd If
'=======================================================
End Sub 'syncFolders
'=======================================================
'=======================================================
Sub syncFiles (sourcePath, targetObj)
'=======================================================
'
'=======================================================-' Recurse through all files in the target object
For Each targetFileObj in targetObj.FilessourceFile = sourcePath & "\" & targetFileObj.Name
'Delete target file if does not exist in source
If Not (objFSO.FileExists(sourceFile)) Then
targetFileObj.Delete true
End If
Next'=======================================================
End Sub 'syncFiles
'=======================================================

Instead of removing the code for the replication process, you just needed to make this change
replicate = false
That would have skipped the process of copying files from the source to the target.
At the moment I am working on the file/folder exclusions. I could do it with a recursive array search, but I decided to use regular expressions as it should run much faster. If you email me, I will send you updates as I complete that.
Michael J

OK, I have updated the script (same link as above). It will now process file and folder exclusions. There are now also switched to bypass hidden files and/or folders.
And you can call the script from the command line and specify whether you want to replicate or sycn (or both) and whether you want to run silently. You call it in this format:
wscript backupScript.vbs [replicate] [sync] [silent]
The parameters must be "trye"/"false" or "0"/"1". They are also optional. If any parameters are missing they will use the values inthe script as the default.
I think I will build out the parameter functionality a little more as well as add logging capability. Any other ideas?
Michael J

Its a great script. I've searched the internet a lot for any script that can do something close to this and the only thing I have found was our very original script which only went through one level of folders.
As for ideas... I'm sure we could come up with tons of them to further increase the power of this script. At that point you might as well market and sell it :)
Thanks again for your help on this.

![]() |
![]() |
![]() |

This post is quite old and has been locked from receiving new replies. Please create a new posting instead.
| Ads by Google |