{"id":30,"date":"2008-09-29T23:19:07","date_gmt":"2008-09-30T03:19:07","guid":{"rendered":"http:\/\/www.mattbertolini.com\/blog\/?p=30"},"modified":"2009-11-03T22:59:19","modified_gmt":"2009-11-04T02:59:19","slug":"simple-backup-script-using-windows-script-host-and-jscript","status":"publish","type":"post","link":"https:\/\/www.mattbertolini.com\/blog\/2008\/09\/29\/simple-backup-script-using-windows-script-host-and-jscript\/","title":{"rendered":"Simple Backup Script using Windows Script Host and JScript"},"content":{"rendered":"<p>At work, I do my development on my local hard disk. I do this mainly for speed. But in between CVS check-ins I need to make sure I don&#8217;t lose any data. The company gives us all network drives that they keep backed up so I decided I would backup my local data to the network drive every night. I didn&#8217;t want to do this every day before I left work so I decided to write a script to automate the process. I had a few goals for this script to accomplish:<\/p>\n<ol>\n<li>Back up all the data in my local folder to a designated folder on my network drive.<\/li>\n<li>Keep each days backup in a separate folder labeled with the date of the backup.<\/li>\n<li>Automatically check the backup directory for backups older than a specified amount of days. I wanted to keep 5 days of backups at a time.<\/li>\n<\/ol>\n<p>So I started to write a simple batch script to accomplish my goals. I always try to start with the simplest language to solve my problem. There is no reason to write a full blown application for a such a simple task. As I was writing the batch script the backing up part was easy to write but I couldn&#8217;t quite get my automatic deletion of older backups to work the way I wanted to. So I decided to abandon the batch script and move up to the next level. I examined the tools I could use and I decided to utilize another scripting technology built into Windows: the Windows Script Host or WSH.<\/p>\n<p>There are two types of languages you can use to write WSH scripts: VBScript and JScript. VBScript is a simple scripting language based on Visual Basic and JScript is the same but based on JavaScript. I am familiar with both Visual Basic and JavaScript so I had a choice to make. I decided to use JScript because I like the syntax style better than Visual Basic.<\/p>\n<p>So I hopped onto MSDN and read up on WSH and JScript syntax and a few hours later, had a finished script. I was pleasantly surprised at the power that the WSH and how easy it was to develop the script. Below is the script:<\/p>\n<pre class=\"brush:javascript\">\/*\r\n * Local to Network Drive Backup Script\r\n * Version 1.0.2 -- 2008-10-22\r\n * Written by Matt Bertolini\r\n *\r\n * Copyright (c) 2008 Matt Bertolini\r\n *\r\n * Permission is hereby granted, free of charge, to any person obtaining a copy\r\n * of this software and associated documentation files (the \"Software\"), to deal\r\n * in the Software without restriction, including without limitation the rights\r\n * to use, copy, modify, merge, publish, distribute, sublicense, and\/or sell\r\n * copies of the Software, and to permit persons to whom the Software is\r\n * furnished to do so, subject to the following conditions:\r\n *\r\n * The above copyright notice and this permission notice shall be included in\r\n * all copies or substantial portions of the Software.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n * THE SOFTWARE.\r\n *\/\r\n\r\n\/\/ Variables to customize\r\nvar appName = \"Local to Network Drive Backup Script\";\r\nvar appVersion = \"1.0.2\";\r\nvar appVersionDate = \"2008-10-22\";\r\nvar sourceDir = \"C:\\\\path\\\\to\\\\files\\\\to\\\\backup\";\r\nvar backupDir = \"C:\\\\path\\\\to\\\\backup\\\\folder\";\r\nvar numDaysSaved = 5;\r\n\r\n\/\/ Editing below this line is not recommended.\r\n\r\n\/\/ Windows Script Host objects\r\nvar out = WScript.StdOut;\r\nvar fso = WScript.CreateObject(\"Scripting.FileSystemObject\");\r\nvar WshShell = WScript.CreateObject(\"WScript.Shell\");\r\nvar currentDateObj = new Date();\r\n\r\n\/\/ Event log constants\r\nvar LOG_EVENT_SUCCESS = 0;\r\nvar LOG_EVENT_ERROR = 1;\r\nvar LOG_EVENT_WARNING = 2;\r\nvar LOG_EVENT_INFORMATION = 4;\r\nvar LOG_EVENT_AUDIT_SUCCESS = 8;\r\nvar LOG_EVENT_AUDIT_FAILURE = 16;\r\n\r\n\/\/ Display script information to console.\r\nout.WriteLine(\"===============================================================================\");\r\nout.WriteLine(\"\\n  \" + appName + \"\\n\");\r\nout.WriteLine(\"  Version \" + appVersion + \" -- \" + appVersionDate);\r\nout.WriteLine(\"  Written by Matt Bertolini\\n\");\r\nout.WriteLine(\"  Script Directory: \" + WScript.ScriptFullName);\r\nout.WriteLine(\"  Backing up files for date: \" + dateToIsoString(currentDateObj));\r\nout.WriteLine(\"  Number of days to keep backups: \" + numDaysSaved);\r\nout.WriteLine(\"  Directory being backed up: \" + sourceDir);\r\nout.WriteLine(\"  Backing up to directory: \" + backupDir);\r\nout.WriteLine(\"\\n===============================================================================\\n\");\r\n\r\n\/\/ Execute script functions.\r\nbackupFolder(sourceDir, backupDir);\r\ndeleteOldBackups(backupDir, numDaysSaved);\r\n\r\nWScript.Quit(0);\r\n\r\nfunction deleteOldBackups(backupDir, numDaysSaved)\r\n{\r\n\t\/\/ Create folder object for backup directory\r\n\tvar backupDirObj = fso.GetFolder(backupDir);\r\n\r\n\tvar fc = new Enumerator(backupDirObj.SubFolders);\r\n\tfor(; !fc.atEnd(); fc.moveNext())\r\n\t{\r\n\t\tvar folderName = fc.item().Name;\r\n\t\tvar cutoffDateObj = new Date();\r\n\t\tcutoffDateObj.setDate(currentDateObj.getDate() - numDaysSaved);\r\n\t\tif(fc.item().DateCreated &lt; cutoffDateObj)\r\n\t\t{\r\n\t\t\tout.Write(\"Deleting backup \" + folderName + \"... \");\r\n\t\t\tfso.DeleteFolder(fc.item(), true);\r\n\t\t\tout.WriteLine(\"done\");\r\n\t\t\tWshShell.LogEvent(LOG_EVENT_SUCCESS, appName + \" - Old backup \" + folderName + \" deleted successfully.\");\r\n\t\t}\r\n\t}\r\n}\r\n\r\nfunction backupFolder(sourceDir, backupDir)\r\n{\r\n\ttry\r\n\t{\r\n\t\tif(fso.FolderExists(backupDir) == false)\r\n\t\t{\r\n\t\t\tout.Write(\"Backup folder does not exist. Creating folder...\");\r\n\t\t\tfso.CreateFolder(backupDir);\r\n\t\t\tout.WriteLine(\"done\");\r\n\t\t}\r\n\t}\r\n\tcatch(e)\r\n\t{\r\n\t\tout.WriteLine(\"Could not create backup folder.\");\r\n\t\tWshShell.LogEvent(LOG_EVENT_ERROR, appName + \" - Could not create backup folder -- \" + e);\r\n\t}\r\n\r\n\ttry\r\n\t{\r\n\t\tout.Write(\"Creating folder for today\\'s backup...\");\r\n\t\tbackupDir = backupDir + \"\\\\\" + dateToIsoString(currentDateObj);\r\n\t\tfso.CreateFolder(backupDir);\r\n\t\tout.WriteLine(\"done\");\r\n\t\tout.Write(\"Backing up files...\");\r\n\t\tfso.CopyFolder(sourceDir, backupDir);\r\n\t\tout.WriteLine(\"done\");\r\n\t\tWshShell.LogEvent(LOG_EVENT_SUCCESS, appName + \" - \" + \"Backup successful.\");\r\n\t}\r\n\tcatch(e)\r\n\t{\r\n\t\tout.WriteLine(\"Backup failed.\");\r\n\t\tWshShell.LogEvent(LOG_EVENT_ERROR, appName + \" - Backup failed -- \" + e);\r\n\t}\r\n}\r\n\r\nfunction dateToIsoString(dateObj)\r\n{\r\n\tvar yearStr = dateObj.getYear().toString();\r\n\tvar monthStr = (dateObj.getMonth() + 1).toString();\r\n\tvar dayStr = dateObj.getDate().toString();\r\n\tif(monthStr.length == 1)\r\n\t{\r\n\t\tmonthStr = \"0\" + monthStr;\r\n\t}\r\n\tif(dayStr.length == 1)\r\n\t{\r\n\t\tdayStr = \"0\" + dayStr;\r\n\t}\r\n\treturn yearStr + \"-\" + monthStr + \"-\" + dayStr;\r\n}<\/pre>\n<p>Next, I wrote a small batch file to call the Windows Script Host with the parameters that I wanted. Here is the batch file:<\/p>\n<pre class=\"brush:plain\">@echo off\r\ncls\r\nsetlocal\r\ntitle Local to Network Drive Backup Script\r\ncall cscript.exe \/\/nologo backup.js\r\nendlocal\r\ncls\r\nexit<\/pre>\n<p>Now for the best part. I am releasing the script under the <a href=\"http:\/\/www.opensource.org\/licenses\/mit-license.php\">MIT License<\/a> so everyone is free to use and modify the script. All you have to do is keep the license at the top. Now I know the script is not perfect so if you find any bugs or have any suggestions on how to improve it, comment in this post and I will see what I can do.<\/p>\n<p><strong>Update 1 &#8211; 2008-10-02<br \/>\n<\/strong><\/p>\n<p>I found a small bug in the ISO date formatting function so I have updated the script and bumped the version up to 1.0.1.<\/p>\n<p><strong>Update 2 &#8211; 2008-10-22<\/strong><\/p>\n<p>I have updated the script to version 1.0.2 by adding some more logging features (to the Windows Event Viewer) and to fix a bug with the deletion of old backups).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>At work, I do my development on my local hard disk. I do this mainly for speed. But in between CVS check-ins I need to make sure I don&#8217;t lose any data. The company gives us all network drives that they keep backed up so I decided I would backup my local data to the &hellip; <a href=\"https:\/\/www.mattbertolini.com\/blog\/2008\/09\/29\/simple-backup-script-using-windows-script-host-and-jscript\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Simple Backup Script using Windows Script Host and JScript<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[103,47],"tags":[96,105,99,100,104,98,101,97,102],"class_list":["post-30","post","type-post","status-publish","format-standard","hentry","category-programming","category-technology","tag-backup","tag-batch-file","tag-host","tag-jscript","tag-msdn","tag-script","tag-vbscript","tag-windows","tag-wsh"],"_links":{"self":[{"href":"https:\/\/www.mattbertolini.com\/blog\/wp-json\/wp\/v2\/posts\/30"}],"collection":[{"href":"https:\/\/www.mattbertolini.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mattbertolini.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mattbertolini.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mattbertolini.com\/blog\/wp-json\/wp\/v2\/comments?post=30"}],"version-history":[{"count":21,"href":"https:\/\/www.mattbertolini.com\/blog\/wp-json\/wp\/v2\/posts\/30\/revisions"}],"predecessor-version":[{"id":92,"href":"https:\/\/www.mattbertolini.com\/blog\/wp-json\/wp\/v2\/posts\/30\/revisions\/92"}],"wp:attachment":[{"href":"https:\/\/www.mattbertolini.com\/blog\/wp-json\/wp\/v2\/media?parent=30"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mattbertolini.com\/blog\/wp-json\/wp\/v2\/categories?post=30"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mattbertolini.com\/blog\/wp-json\/wp\/v2\/tags?post=30"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}