-2

So this one's a multi-parter (Windows 7).

I have a folder structure as so:

C:
  SyncFolder
    Backups
  [User]
    FolderA
      Subfolder1
      Subfolder2
    FolderB
      Subfolder3

My aim is to use the folder 'SyncFolder' as a backup system for certain files (Sync folder is actually a folder placed there by a file syncing service).

At present, I have the following within the Sync folder:

  • a .bat file containing a ROBOCOPY command (which copies 1 file)
  • a .vbs file which is used to call the .bat file (to avoid the CMD window appearing). This VBS file is being called once per hour by Windows Task Scheduler
  • the file which is being copied

So here are my questions:

I'm looking for a code (preferably an edit to the existing .bat, as I'm not overly-technical) which can:

  • Copy Subfolder1 in its entirety into a .zip file, which is named YYYYMMDDHHMM_SubFolder1_Backup (where the date & time is automatically populated)
  • Move the newly-created .zip file to SyncFolder\Backups (or create it there in the first place?)
  • Deletes (or overwrites?) the previous backup
  • Repeats for each Subfolder specified (perhaps as an additional command line?) -- I'm not expecting the commands to identify the folders. I would specify the folders myself
  • Logs the details of the backup to a .log file located in SyncFolder (i.e. Name of .zip created, Date&Time of backup, size of .zip created)

I'm aware this might be a bit ambitious for CMD or a .bat, but I'm open to any suggestions, but please do bear in mind that I'm not highly technical, so any walk-throughs would be immensely appreciated!

Edit:

Here is my attempt with the .bat code:

@echo off

robocopy "C:\[USER]\[FolderA]\[SubFolder1]" "C:[SyncFolder]\Backups\BackupTest1.zip" *.* /dcopy:T /r:5 /w:5 /log+:"C:\[SyncFolder]\CopyLog.log" /bytes /ts /np

... I've tried this, without luck. This command works, but only creates a folder named BackupTest1.zip (which isn't actually a .zip).

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
M R
  • 77
  • 2
  • 9
  • SO is neither a place where other people write code for you, nor is it a replacement for getting at least a basic understanding of the language you're trying to use first (e.g. by working your way through a tutorial). We're willing to help, but we expect you to have done your homework first. Show the code that doesn't work the way you want (a [mcve] to be precise), and explain what you expected the code to do and what it actually does. Include all error messages you're getting. As it stands your question is way too broad. – Ansgar Wiechers Nov 21 '17 at 11:23
  • Edited question to include my attempt at code – M R Nov 21 '17 at 11:46
  • check [this](https://stackoverflow.com/questions/28043589/how-can-i-compress-zip-and-uncompress-unzip-files-and-folders-with-bat) – npocmaka Nov 21 '17 at 11:48
  • Zip archives are compressed files, not folders. `robocopy` doesn't support treating zip archives as folders. Try [7-zip](http://7-zip.org/). – Ansgar Wiechers Nov 21 '17 at 15:30

2 Answers2

1

Create a file using notepad, let's save it as ZipCMD.vbs then add the following code.

Set objArgs = WScript.Arguments
Set FS = CreateObject("Scripting.FileSystemObject")
InputFolder = FS.GetAbsolutePathName(objArgs(0))
ZipFile = FS.GetAbsolutePathName(objArgs(1))

CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" & Chr(5) & Chr(6) & String(18, vbNullChar)

Set objShell = CreateObject("Shell.Application")
Set source = objShell.NameSpace(InputFolder).Items

objShell.NameSpace(ZipFile).CopyHere(source)
wScript.Sleep 3000

Now you can run from cmdline

ZipCMD.vbs "C:\Frank\Folder A\Sub Folder 1" "C:\SyncFolder\Backups\BackupTest1.zip"

if you want to manually zip anything from cmd line.

If you want to schedule it, you can either just add the VBS file, or write a mybackup.cmd file and put the full string below in it and schedule that instead.

mybackup.cmd

ZipCMD.vbs "C:\Frank\Folder A\Sub Folder 1" "C:\SyncFolder\Backups\BackupTest1.zip"
Gerhard
  • 22,678
  • 7
  • 27
  • 43
  • This solves the .zip problem perfectly, but I have a couple more questions for you: Firstly: What is the purpose of the 'Sleep 3000'? -- Why 3000? (If it's to do with the amount of time it takes to zip a file, should I extend the 3000 to allow for large file being zipped (>500MB)? Secondly: How can I edit the CMD section to append the current YYYYMMDDhhmm to the zip file's name? I assume it's something using 'set Year %Year%'? Lastly: Is it possible to add a logging element to the CMD file? - Records date of action, and size of .zip? – M R Nov 21 '17 at 13:36
  • the sleep command is required to let the zip command execute, the 3000 = 3 seconds, so if you need more time, then just increase it. as for the command for date, I will amend my answer. – Gerhard Nov 21 '17 at 13:48
  • I look forward to seeing your updated answer. One thing I've thought of is this: If the .CMD is creating a new .zip with a new name each time, what can be done to delete the old one? i.e. If I create a .zip backup on 201711211400, then one tomorrow at 201711221400, how would I go about deleting the old one? – M R Nov 21 '17 at 14:40
  • Also, is there a way to do this without the pre-defined 'Sleep', and rather just say 'Run until the zipping has finished'? – M R Nov 21 '17 at 16:25
  • Alternatively, could this be done by updating the existing .zip file using your ZipCMD module, and then somehow renaming it with the current date? – M R Nov 21 '17 at 16:46
  • Instead of a hard time limit you may want to check the item count in the zip archive. [Related](https://stackoverflow.com/a/22050803/1630171). – Ansgar Wiechers Nov 22 '17 at 00:29
0

Okay, so building on Gerhard's answer, I've got this:

In C:\SyncFolder, create ZipCMD.vbs using the following code in Notepad

Set objArgs = WScript.Arguments
Set FS = CreateObject("Scripting.FileSystemObject")
InputFolder = FS.GetAbsolutePathName(objArgs(0))
ZipFile = FS.GetAbsolutePathName(objArgs(1))

CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" & Chr(5) & Chr(6) & String(18, vbNullChar)

Set objShell = CreateObject("Shell.Application")
Set source = objShell.NameSpace(InputFolder).Items

objShell.NameSpace(ZipFile).CopyHere(source)
wScript.Sleep 3000

I've also created a Backups.bat in C:\Syncfolder using the following code in Notepad

@echo off
for /f "delims=" %%a in ('wmic OS Get localdatetime  ^| find "."') do set dt=%%a
set YYYY=%dt:~0,4%
set MM=%dt:~4,2%
set DD=%dt:~6,2%
set HH=%dt:~8,2%
set Min=%dt:~10,2%
set Sec=%dt:~12,2%
set stamp=%YYYY%%MM%%DD%%HH%%Min%
rem parameters set for use later


Del "C:\SyncFolder\*_BackupTest1.zip"
rem This line removes the old backup first (Not ideal. Open to suggestions)

ZipCMD.vbs "C:\Users\[USER]\[FolderA]\[SubFolder1]" "C:\[SyncFolder]\BackupTest1.zip"
rem This line copies files and folders from the Source to the Destination into a named .zip, without a date.

copy "C:\[SyncFolder]\BackupTest1.zip" "C:\[SyncFolder]\%stamp%_BackupTest1.zip"
rem This line creates a copy of the un-dated file, but appends a Date and Time from the parameters defined at the start of the file.

Del "C:\[SyncFolder]\BackupTest1.zip"
rem This line deletes the un-dated file, leaving only the current, dated backup.

Set File="*_BackupTest1.zip"
FOR /F "usebackq" %%A IN ('%file%') DO set size=%%~zA
rem These lines define a new parameter defined by the .zip's size

Echo %stamp%_BackupTest1.zip    %Size% >>BackupLog.log
rem This last line appends a line to a log file containing the name of the .zip created (which contains its' date) and its' size.

The second section of the above .bat (after defining initial parameters) can be repeated for multiple folders.

Lastly, I create a RunBackups.vbs in C:\SyncFolder using the following code in Notepad

Set WshShell = CreateObject("WScript.Shell" ) 
WshShell.Run chr(34) & "C:\[SyncFolder]\Backups.bat" & Chr(34), 0 
Set WshShell = Nothing

This runs the .bat without having the black CMD window appear (i.e. running in 'silent' mode), and is the file I call upon using Task Scheduler to automate the backup process.

Unfortunately, there are still some issues with this:

  • In the ZipCMD.vbs file, the wScript.Sleep 3000 line causes issues on any .zip files which would take longer than 3 seconds to create. This could be extended, but having it hard-coded may prove troublesome. Open to suggestions as to how to get around this?
  • In the Backups.bat file, the old backup is deleted prior to the creation of the new backup. This is because I use *_TestBackup1.zip to identify the old backup, which, if used after the backup's creation, would delete both new and old backups. Perhaps moving the first Del command to immediately after the first ZipCMD.vbs command would help, as a backup would always exist?
M R
  • 77
  • 2
  • 9