Hmmm, this sounds more like a backup plan rather then a sync plan.
The notion of "Syncing" is to keep files in multiple places the same version. If someone deletes a file, it is expected one would want to delete the file at all other places to.
Rather, there are some backup programs that can monitor when files are altered, then back them up to another location. In fact you likely want multiple levels of backups in multiple places in case a hard drive fails.
7zip can add files to, and update files within, an archive without deleting them while compressing them and encrypting them. Maybe you can run 7zip on a schedule every hour or so and alternate the destination. It comes with a command line version with lots of options. It even comes in Linux flavors too.
Depending on the complexity of your office, you might consider an older slower computer dedicated to the task of gathering files from other places and backing them up. Go older and slower so no one will be tempted to use it as a workstation. Computers and hard drives these days are pretty cheap especially on eBay. Go headless and you don't even need a monitor keyboard and mouse.
A while ago I rolled my own using 7zip command line that would backup every night and keep 5 levels of backups in 2 locations. It ran from a batch file called from Windows scheduler every night. Worked great.
Mark.
Edit:
Michael asked for my code, I will post it here, called BackupStuff.wbt. It was written a while ago using a (then) free program called WinBatch. It is a simple scripting program, but makes for good psudo-code. The WinBatch code calls a batch file also included below.
;Winbatch program to backup our stuff
; usage:
; BackUpStuff computer kind source [mail] [temp]
; where
; computer is the name of the source computer to backup (ie. Gandalf, or Froto)
; kind is the source kind of thing to back (ie. Storage, or disks)
; source is the drive and path on name (ie \\Gandalf_D\disks or I:)
; mail (must be the literal word "mail") is an optionl trigger to tell this program to kill the mail program on gandalf
; (later will expand to kill mail on Shire too.)
; temp (must be the literal word "temp") is a trigger to use a temporary local folder, then copy the zip files en-mass
; how it works:
; setup some working variables
; make a log entry
; if necessary, stop the mail client
; verify we have access to the target folder
; remove / shuffle old versions of backups.
; do the deed (zip stuff)
; make a log entry
; verify the backup exists. if not, error
IntControl(12,5,0,0,0) ; allow winbatch to quit quietly
IntControl(29,@TAB,0,0,0) ; set tab as delimiter for windows XP compatability
;-------------------------------------------------------
;
; IIIIIIIIII NNN NN IIIIIIIIII TTTTTTTTTT
; II NNNN NN II TTTTTTTTTT
; II NN N NN II TT
; II NN NN NN II TT
; II NN N NN II TT
; II NN NNNN II TT
; IIIIIIIIII NN NNN IIIIIIIIII TT
;
our_title = "BackStuffUp"
starting_folder = DirGet()
;
;get some environment variables
;
computer_were_on = Environment("COMPUTERNAME")
computer_to_do = Param1
computer_to_do = StrCat(StrUpper(StrSub(computer_to_do,1,1)),StrLower(StrSub(computer_to_do,2,-1)))
kind = Param2
source = param3
kill_mail = @FALSE
use_temp = @false
if IsDefined(param4)
if StrUpper(param4) == "MAIL"
kill_mail = @TRUE
else
if StrUpper(param4) == "TEMP"
use_temp = @true
endif
endif
endif
if IsDefined(param5)
if StrUpper(param5) == "MAIL"
kill_mail = @TRUE
else
if StrUpper(param5) == "TEMP"
use_temp = @true
endif
endif
endif
if computer_were_on == "GANDALF"
backup_to_computer = "\\Frodo\Memory_Omega_180G"
temp_file_folder = "\\Gandalf\Memory_Gamma\temp_file_backups\"
temp_zip_folder = "\\Gandalf\Memory_Gamma\temp_zip_backups\"
else
if computer_were_on == "FRODO"
backup_to_computer = "E:"
temp_file_folder = "c:\temp_file_backups\"
temp_zip_folder = "c:\temp_zip_backups\"
else
message(our_title, "computer_were_on not Gandalf or Frodo")
GoTo Done
endif
endif
busy_filename_prefix = StrCat(starting_folder,"BackupBusy_")
busy_filename = StrCat(busy_filename_prefix, kind)
target_folder_1 = StrCat(backup_to_computer, "\Backups\", computer_to_do, "\", kind, "_1")
target_folder_2 = StrCat(backup_to_computer, "\Backups\", computer_to_do, "\", kind, "_2")
target_folder_3 = StrCat(backup_to_computer, "\Backups\", computer_to_do, "\", kind, "_3")
target_folder_4 = StrCat(backup_to_computer, "\Backups\", computer_to_do, "\", kind, "_4")
log_filename = "\\Gandalf\GandalfD_Storage\batches\BackupTool\BackUpStuff.log"
;
;
;handle log
GoSub StartTheLog
FileWrite(log_file,"")
FileWrite(log_file,StrCat(log_line_prefix, "Starting Job ", computer_to_do, " ", kind))
GoSub StopTheLog
;
;
; verify the target computer is available
;
;
;handle log
GoSub StartTheLog
FileWrite(log_file,StrCat(log_line_prefix, "verifying target computer"))
GoSub StopTheLog
;
; sometimes it takes a while to wake up the network or spin up the disks
retry_count = 5
While !DirExist(backup_to_computer)
delay(10)
retry_count = retry_count - 1
if retry_count < 1
GoSub StartTheLog
FileWrite(log_file,StrCat(log_line_prefix, "Backing up ", kind , " Can't find backup_to_computer"))
GoSub StopTheLog
msg = StrCat("Backing up ", kind , " Can't find ", backup_to_computer, ", Try Again?")
if AskYesNo(our_title, msg) == @YES
retry_count = 2
else
GoTo Done
endif
endif
endwhile
;
; LL OOOOOO CCCCCC KK KK
; LL OO OO CC CC KK KKKK
; LL OO OO CC KK KKK
; LL OO OO CC KKKKK
; LL OO OO CC KK KKK
; LLLLLLLL OO OO CC CC KK KKKK
; LLLLLLLLLL OOOOOO CCCCCC KK KK
;
; handle multiple instances
;
;first see if there is another instance of THIS script running on this computer
; (should be impossable as windows scheduler should prevent this)
; OK to launch this on different computer , it will just wait till the other is done
GoSub StartTheLog
FileWrite(log_file,StrCat(log_line_prefix, "Verifying duplicate instance of this backup"))
GoSub StopTheLog
;
if FileExist(busy_filename)
message(our_title, StrCat("Oops, ", kind, " is already running, can't happen"))
GoTo Done
endif
GoSub StartTheLog
FileWrite(log_file,StrCat(log_line_prefix, "Checking to see if another backup is running"))
GoSub StopTheLog
;
;now see if another backup script is running, hang here and wait till done
busy_list = FileItemize(StrCat(busy_filename_prefix,"*"))
if ItemCount(busy_list, @TAB) > 0
; yes, tell the log about it
GoSub StartTheLog
FileWrite(log_file,StrCat(log_line_prefix, computer_to_do, " ", kind, " Waiting for another Backup"))
GoSub StopTheLog
endif
while ItemCount(busy_list, @TAB) > 0
; wait here till the other instance quits
delay(10)
busy_list = FileItemize(StrCat(busy_filename_prefix,"*"))
endwhile
GoSub StartTheLog
FileWrite(log_file,StrCat(log_line_prefix, "No other backup running, continuing..."))
GoSub StopTheLog
;
; now, create our own instance of busy
old_mode = ErrorMode(@OFF)
:Retry1
filenum = FileOpen(busy_filename,"WRITE")
if filenum == 0
Display(2, our_title, "Retrying 1")
GoTo Retry1
endif
ErrorMode(old_mode)
FileClose(filenum)
;
; BBBBBBBB EEEEEEEEEE GGGGGG IIIIIIIIII NNN NN
; BB BB EE GG GG II NNNN NN
; BB BB EE GG II NN N NN
; BBBBBBBBB EEEEEEE GG GGGGG II NN NN NN
; BB BB EE GG GG II NN N NN
; BB BB EE GG G II NN NNNN
; BBBBBBBB EEEEEEEEEE GGGGGG IIIIIIIIII NN NNN
;
;
;
; TTTTTTTTTT EEEEEEEEEE SSSSSS TTTTTTTTTT TTTTTTTTTT AA RRRRRRRR GGGGGG EEEEEEEEEE TTTTTTTTTT
; TTTTTTTTTT EE SS SS TTTTTTTTTT TTTTTTTTTT AAAAAA RR RR GG GG EE TTTTTTTTTT
; TT EE SS TT TT AA AA RR RR GG EE TT
; TT EEEEEEE SSSSSS TT TT AA AA RRRRRRRR GG GGGGG EEEEEEE TT
; TT EE SS TT TT AAAAAAAAAA RR RR GG GG EE TT
; TT EE SS SS TT TT AA AA RR RR GG G EE TT
; TT EEEEEEEEEE SSSSSS TT TT AA AA RR RR GGGGGG EEEEEEEEEE TT
;
GoSub StartTheLog
start_time = now
FileWrite(log_file,StrCat(log_line_prefix, "Testing target ", computer_to_do, " ", kind))
GoSub StopTheLog
; see if we have access to the target folder
test_counter = 5
:TestAgain
if DirExist(target_folder_1) then goto TargetFolderFound
DirMake(target_folder_1)
if DirExist(target_folder_1) then goto TargetFolderFound
delay(10)
test_counter = test_counter - 1
if test_counter == 0
GoSub StartTheLog
FileWrite(log_file,StrCat(log_line_prefix, "Error ", computer_to_do, " ", kind))
FileWrite(log_file, StrCat(log_line_prefix, target_folder_1, ' not found');
FileWrite(log_file,"")
GoSub StopTheLog
message(our_title,StrCat(target_folder_1, ' not Found')
Goto Done
endif
goto TestAgain
:TargetFolderFound
;
; RRRRRRRR EEEEEEEEEE NNN NN AA MMM MMM EEEEEEEEEE
; RR RR EE NNNN NN AAAAAA MMMM MMMM EE
; RR RR EE NN N NN AA AA MM MMMM MM EE
; RRRRRRRR EEEEEEE NN NN NN AA AA MM MM MM EEEEEEE
; RR RR EE NN N NN AAAAAAAAAA MM MM MM EE
; RR RR EE NN NNNN AA AA MM MM MM EE
; RR RR EEEEEEEEEE NN NNN AA AA MM MM MM EEEEEEEEEE
;
; remove old backups, and rename
FileDelete(StrCat(target_folder_4, "\*.*"))
DirRemove(target_folder_4)
if DirExist(target_folder_3) then DirRename(target_folder_3, target_folder_4)
FileDelete(StrCat(target_folder_3, "\*.*"))
DirRemove(target_folder_3)
if DirExist(target_folder_2) then DirRename(target_folder_2, target_folder_3)
FileDelete(StrCat(target_folder_2, "\*.*"))
DirRemove(target_folder_2)
if DirExist(target_folder_1) then DirRename(target_folder_1, target_folder_2)
DirMake(target_folder_1)
;
;
; CCCCCC OOOOOO PPPPPPPP YY YY
; CC CC OO OO PP PPP YY YY
; CC OO OO PP PPP YY YY
; CC OO OO PPPPPPPP YYYY
; CC OO OO PP YY
; CC CC OO OO PP YY
; CCCCCC OOOOOO PP YY
;
; Kill mail (maybe)
if kill_mail then runwait("\\Gandalf\GandalfD_Storage\batches\KillThunderbird.wbt",'')
; copy all files to a temp folder and run zip on the temp folder
if use_temp
if computer_were_on == "GANDALF"
if StrUpper(computer_to_do) == "GANDALF"
ipg = "1"
else
ipg = "25"
endif
else
if StrUpper(computer_to_do) == "GANDALF"
ipg = "50"
else
ipg = "50"
endif
endif
GoSub StartTheLog
FileWrite(log_file,StrCat(log_line_prefix, "Copying from ", source, " to ", temp_file_folder))
GoSub StopTheLog
runwait("I:\batches\DelFoldersNFiles.bat", temp_file_folder)
DirMake(temp_file_folder)
rich_commands = StrCat('"', source, '"', ' ', temp_file_folder, ' /r:2 /w:2 /e /XF RoboCopy_source.log /log:\\Gandalf\GandalfD_Storage\batches\BackupTool\RoboCopy_source.log /tee /ipg:',ipg)
runwait("\\Gandalf\GandalfD_Storage\Utilitie\robocopy.exe", rich_commands)
GoSub StartTheLog
FileWrite(log_file,StrCat(log_line_prefix, computer_to_do, " ", kind, "Robocopy Done"))
GoSub StopTheLog
endif
;
; ZZZZZZZZZZ IIIIIIIIII PPPPPPPP
; ZZZZ II PP PPP
; ZZ II PP PPP
; ZZ II PPPPPPPP
; ZZ II PP
; ZZZZ II PP
; ZZZZZZZZZZ IIIIIIIIII PP
;
; command line was too long for WinBatch to handle (more then 10 parameters), so use a batch file to do work
if use_temp
zip_source = StrCat('"', temp_file_folder, '*"')
temp_name = StrCat(kind, ".zip")
zip_target = StrCat(temp_zip_folder, temp_name)
runwait("I:\batches\DelFoldersNFiles.bat", temp_zip_folder)
DirMake(temp_zip_folder)
else
zip_source = StrCat('"', source, '\*"')
zip_target = StrCat(target_folder_1, "\", kind, ".zip")
endif
GoSub StartTheLog
FileWrite(log_file,StrCat(log_line_prefix, "Starting Zip ", computer_to_do, " ", kind, " from ", zip_source, " to ", zip_target))
GoSub StopTheLog
run("ZipIt.bat", StrCat(zip_target, ' ', zip_source))
WinWaitExist("~7z.exe",60)
WinWaitClose("~7z.exe")
; delete the temp FILES
if use_temp
runhidewait("I:\batches\DelFoldersNFiles.bat", temp_file_folder)
endif
; make an entry into the log file
GoSub StartTheLog
FileWrite(log_file,StrCat(log_line_prefix, computer_to_do, " ", kind, "Ziping Finished, starting Robocopy"))
GoSub StopTheLog
; restart mail (maybe)
if kill_mail then run("C:\Program Files\Mozilla Thunderbird\thunderbird.exe",'')
;
; CCCCCC OOOOOO PPPPPPPP YY YY
; CC CC OO OO PP PPP YY YY
; CC OO OO PP PPP YY YY
; CC OO OO PPPPPPPP YYYY
; CC OO OO PP YY
; CC CC OO OO PP YY
; CCCCCC OOOOOO PP YY
;
if kill_mail
if DiskExist("B:")
FileCopy(StrCat(zip_target, ".*") , "B:\MyBackups\", @FALSE)
endif
endif
if use_temp
GoSub StartTheLog
FileWrite(log_file,StrCat(log_line_prefix, "Copying from ", temp_zip_folder, " to ", target_folder_1))
GoSub StopTheLog
rich_commands = StrCat(temp_zip_folder, ' ', target_folder_1, ' /MOV /XF RoboCopy_dest.log /log:\\Gandalf\GandalfD_Storage\batches\BackupTool\RoboCopy_dest.log /tee /ipg:', ipg)
runwait("\\Gandalf\GandalfD_Storage\Utilitie\robocopy.exe", rich_commands)
runhidewait("I:\batches\DelFoldersNFiles.bat", temp_zip_folder)
GoSub StartTheLog
FileWrite(log_file,StrCat(log_line_prefix, computer_to_do, " ", kind, "Robocopy Done"))
GoSub StopTheLog
endif
;
; DDDDDDDD OOOOOO NNN NN EEEEEEEEEE
; DD DD OO OO NNNN NN EE
; DD DD OO OO NN N NN EE
; DD DD OO OO NN NN NN EEEEEEE
; DD DD OO OO NN N NN EE
; DD DD OO OO NN NNNN EE
; DDDDDDDD OOOOOO NN NNN EEEEEEEEEE
;
; make an entry into the log file
GoSub StartTheLog
file_to_search_for = StrCat(target_folder_1, "\", kind, ".zip.001")
if !FileExist(file_to_search_for) then
file_to_search_for = StrCat(target_folder_1, "\", kind, ".zip")
if !FileExist(file_to_search_for) then
FileWrite(log_file,StrCat(log_line_prefix, "Error Target zip file ", kind, " not found"));
message(our_title,StrCat("Error Target zip file ", kind, " not found"))
message(our_title,"You should verify files on Frodo, and rename folders as needed to preserve any existing backups")
endif
endif
time_diff = TimeSubtract(now, start_time)
time_diff = StrSub(time_diff, 10, 8)
FileWrite(log_file, StrCat(log_line_prefix, "Time to Backup ", kind, " - ", time_diff))
GoSub StopTheLog
:Done
; stop this instance
FileDelete(busy_filename)
exit
;
; subroutines
;
:StartTheLog
now = TimeYmdHms()
log_file = FileOpen(log_filename,"APPEND")
log_line_prefix = StrCat("20", StrSub(now,1,2), "/", StrSub(now,4,2), "/", StrSub(now,7,2), " ", StrSub(now, 10, -1), " - ")
return
:StopTheLog
FileClose(log_file)
Drop(now)
return
This is the batch file called Zipit.bat (place in your path somewhere.)
start /I /SHARED /BELOWNORMAL 7z a -tzip -r -v1000m -mx7 -spf2 -p<place your password for encrypting the zip file here> %1 %2
Enjoy, Mark.