0

My office is using a program that relies heavily on files in a folder on the network, Recently someone deleted a file or two and threw the whole office in a tizzy. I'm trying to come up with an idea to make sure it doesn't happen again.

My idea is that I will have all the network files in another folder that is synced to the original folder. I am looking for software that with sync a folder in such a way that even if someone deletes a file from the destination folder it will get automatically restored.

I haven't found the right program yet. Any ideas?

6
  • 2
    Help us help you. Please specify an operating system and budget. Commented Aug 16, 2016 at 5:42
  • anyway it sounds like a job for rsync! -- and by the way: i hope there are backups at an other place!?! Commented Aug 16, 2016 at 5:50
  • 1
    In the title, do you mean "with" instead of "without"?
    – Nicolas Raoul
    Commented Aug 16, 2016 at 6:34
  • 1
    What file sharing technology is your network using? WebDAV? CIFS? NFS? Another? A screenshot of the Properties of the shared drive might help us find out. We can't help you without this information.
    – Nicolas Raoul
    Commented Aug 16, 2016 at 6:35
  • 1
    Also, what if you really need to delete a file? Should it be removed from the share once it's removed from the "sync-copy", or how should that work? Wouldn't a manual restore be favorable (as it makes things easier when it comes to "real deletion" – and also avoids making the users "too careless" about deleting stuff)?
    – Izzy
    Commented Aug 16, 2016 at 6:37

3 Answers 3

0

To fully get this to operate optimally, there are a few things you should implement (or the IT department). The first thing I would suggest is implementing Shadow Copies:

Shadow Copy (also known as Volume Snapshot Service, Volume Shadow Copy Service or VSS) is a technology included in Microsoft Windows that allows taking manual or automatic backup copies or snapshots of computer files or volumes, even when they are in use.

With this enabled, you can restore from previous "Snap Shots" throughout your backup history (assuming you have NTFS permissions to the file(s) in question).

Secondly, replication is a result of having sufficient privledges to modify the data in the directory. If you are not required to modify the data, ensure the user only has Read-Only NTFS permissions to the directory.

Now, seeing as this is Software Recommendations, I'll recommend just that; DSynchronize.

A freeware application that allows you to sync directories (mirroring), with BiDirectional support, encryption and scheduling.

0

This can be solved by setting correct permissions on the server.

Specifically:

  • Read and Write access for administrators
  • Read-only permission for all others

Most folder sharing technologies allow this kind of settings. If your server does not allow setting permissions for group of users, I recommend switching to Alfresco (gratis and open source. Disclaimer: I contribute to it). You can configure it to be accessible as a network shared drive.

2
  • Read only access is not always the needed solution - I may need to be able to edit the file, just not delete it...
    – ivanivan
    Commented Apr 29, 2017 at 14:14
  • This answers how to perhaps restrict certain users from deleting files, but in this case what if the person deleting the file was someone authorised to perform it? I think the OP wants more of an answer as to how to restore it if needed, not to prevent users modifying data. Props to Alfresco though, it seems a good tool.
    – DankyNanky
    Commented Jul 28, 2017 at 10:29
0

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.

1
  • Mark, you're suggesting implementing 7Zip CLI for the solution of restoring data? I get you can use 7Zip FM to backup data and run it as a service, but I would not rely on this to be my backup tool. Care to share the CLI code for us?
    – DankyNanky
    Commented Jul 28, 2017 at 10:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.