{"id":1264,"date":"2009-12-21T01:03:10","date_gmt":"2009-12-21T07:03:10","guid":{"rendered":"http:\/\/gregsowell.com\/?p=1264"},"modified":"2010-01-27T10:48:46","modified_gmt":"2010-01-27T16:48:46","slug":"automated-mikrotik-backups-from-windows-securely","status":"publish","type":"post","link":"https:\/\/gregsowell.com\/?p=1264","title":{"rendered":"Automated Mikrotik Backups From Windows Securely"},"content":{"rendered":"<p>So what this little autoit script does is <a href=\"http:\/\/www.chiark.greenend.org.uk\/~sgtatham\/putty\/download.html\">SSH(using plink)<\/a> into your Mikrotiks and issue the export command.  It has a GUI to add all of your routers, and you use the windows scheduler to run the program to do automated backups.<\/p>\n<p>It creates a sub folder in the script directory.  It then creates a text file in the format<br \/>\nSCRIPT-DIRECTORY\\YEAR\\DESCRIPTION-IP ADDRESS-MONTH-DAY.TXT  <\/p>\n<figure id=\"attachment_1266\" aria-describedby=\"caption-attachment-1266\" style=\"width: 503px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/gregsowell.com\/wp-content\/uploads\/2009\/12\/mtkbup1.JPG\" alt=\"The program in all it&#039;s glory...;)\" title=\"mtkbup1\" width=\"503\" height=\"471\" class=\"size-full wp-image-1266\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2009\/12\/mtkbup1.JPG 503w, https:\/\/gregsowell.com\/wp-content\/uploads\/2009\/12\/mtkbup1-300x280.jpg 300w\" sizes=\"auto, (max-width: 503px) 100vw, 503px\" \/><figcaption id=\"caption-attachment-1266\" class=\"wp-caption-text\">The program in all it's glory...;)<\/figcaption><\/figure>\n<p>Everything is pretty straight forward.  IP\/Description\/Username\/Password.  If you want to add a new device, just fill in the blanks and hit add\/update.  If you click a device over in the list, it will populate the text fields with its information.  If you want to update the entry, make any changes and then click the add\/update button.<\/p>\n<p>To back them all up, click the backup all button.  To backup a single entry, highlight it in the list, and then click the backup single button.<\/p>\n<p>If you want to delete an entry, highlight it and click delete.<\/p>\n<p>There is a caveat with plink.  When hitting a device via ssh for the first time it requires you to accept the host key&#8230;and this has to be done manually.  So, when you add a new device for the first time, it will connect and ask you to accept the key.  After you accept and close, everything will be automatic.<\/p>\n<p><strong>Schedule it to run automatically<\/strong><br \/>\n<strong>*NOTE* <\/strong> Whatever user account on the windows machine you accept the host keys with, is the account you need to run the scheduled task as!<\/p>\n<p><a href=\"http:\/\/support.microsoft.com\/kb\/308569\">Schedule a windows task<\/a> to run the MikrotikBackup.exe program, and then add anything after the program name like the following:<\/p>\n<p><em>c:\\scripts\\MikrotikBackup.exe -GregRocks<\/em><\/p>\n<p>Adding anything after the executable makes it run silently and backup all routers.<\/p>\n<p>You can download the executable from here: <div class=\"wp-block-button\">\n<a  data-e-Disable-Page-Transition=\"true\" class=\"dlm-download-link wp-block-button__link wp-element-button\" title=\"\" href=\"https:\/\/gregsowell.com?download=5683&amp;tmstv=1783646942\" rel=\"nofollow\" id=\"download-link-5683\" data-redirect=\"false\" >\n\tMikrotikBackup\t(4615 downloads\t)\n<\/a>\n<\/div>\n.<\/p>\n<p>Here&#8217;s the autoit code:<\/p>\n<pre class=\"gs-code\"><code class=\"language-plaintext\">#include &lt;ButtonConstants.au3&gt;\r\n#include &lt;EditConstants.au3&gt;\r\n#include &lt;GUIConstantsEx.au3&gt;\r\n#include &lt;GuiIPAddress.au3&gt;\r\n#include &lt;GUIListBox.au3&gt;\r\n#include &lt;StaticConstants.au3&gt;\r\n#include &lt;WindowsConstants.au3&gt;\r\n#include &lt;File.au3&gt;\r\n#include &lt;Array.au3&gt;\r\n\r\nFileInstall(&quot;C:\\Documents and Settings\\greg\\Desktop\\autoit\\mikrotikBackup\\plink.exe&quot;, @ScriptDir &amp; &quot;\\plink.exe&quot;)\r\n\r\nDim $aConfig\r\n\r\n;check if they are running backup version\r\nif $CmdLine[0] &gt; 0 Then\r\n\t;they are running it from the command line\r\n\t;pull config file\r\n\t_BackupAll()\r\n\t;exit once done\r\n\tExit\r\nEndIf\r\n\r\n;gui goodness\r\n#Region ### START Koda GUI section ### Form=C:\\Documents and Settings\\greg\\Desktop\\autoit\\mikrotikBackup\\MikrotikBackup.kxf\r\n$Form1 = GUICreate(&quot;GregSowell.com Mikrotik Backup&quot;, 497, 446, 192, 114)\r\n$List1 = GUICtrlCreateList(&quot;&quot;, 16, 16, 273, 422)\r\n$BtnDelete = GUICtrlCreateButton(&quot;Delete&quot;, 312, 406, 73, 25, $WS_GROUP)\r\n$BtnAll = GUICtrlCreateButton(&quot;Backup All&quot;, 312, 283, 73, 25, $WS_GROUP)\r\n$BtnSingle = GUICtrlCreateButton(&quot;Backup Single&quot;, 312, 321, 73, 25, $WS_GROUP)\r\n$IPAddress1 = GUICtrlCreateInput(&quot;0.0.0.0&quot;, 312, 32, 129, 17)\r\n$InDescription = GUICtrlCreateInput(&quot;&quot;, 312, 88, 169, 21)\r\n$Label1 = GUICtrlCreateLabel(&quot;IP Address&quot;, 312, 16, 55, 17)\r\n$Label2 = GUICtrlCreateLabel(&quot;Description&quot;, 312, 65, 57, 17)\r\n$Label3 = GUICtrlCreateLabel(&quot;Username&quot;, 312, 129, 52, 17)\r\n$Label4 = GUICtrlCreateLabel(&quot;Password&quot;, 312, 190, 50, 17)\r\n$InUsername = GUICtrlCreateInput(&quot;admin&quot;, 312, 147, 169, 21)\r\n$InPassword = GUICtrlCreateInput(&quot;&quot;, 312, 207, 169, 21);, BitOR($ES_PASSWORD,$ES_AUTOHSCROLL))\r\n$BtnUpdate = GUICtrlCreateButton(&quot;&amp;Add\/Update&quot;, 312, 246, 73, 25, $WS_GROUP)\r\nGUISetState(@SW_SHOW)\r\n#EndRegion ### END Koda GUI section ###\r\n\r\n$ListLocation = 1\r\n\r\n;check for config file\r\nif not FileExists(@ScriptDir &amp; &quot;\\backupconfig.txt&quot;) Then\r\n\t;doesn&#039;t exist, so create our dummy file\r\n\t$fConfig = FileOpen(@ScriptDir &amp; &quot;\\backupconfig.txt&quot;, 1)\r\n\tFileWriteLine($fConfig, &quot;demo delete me,1.1.1.1,delete,me&quot; &amp; @CRLF)\r\n\tFileClose($fConfig)\r\nEndIf\r\n\r\n\t$fCommand = FileOpen(@ScriptDir &amp; &quot;\\commands.txt&quot;, 2)\r\n\tFileWriteLine($fCommand, &quot;export&quot; &amp; @CRLF)\r\n\tFileClose($fCommand)\r\n\r\n;load in the config file\r\n_LoadConfig()\r\n\r\n;main running loop\r\nWhile 1\r\n\t$nMsg = GUIGetMsg()\r\n\tSwitch $nMsg\r\n\t\tCase $BtnAll\r\n\t\t\t;backup all of them\r\n\t\t\t_BackupAll()\r\n\t\tCase $BtnSingle\r\n\t\t\t;backup single guy\r\n\t\t\t_BackupSingle()\r\n\t\tcase $GUI_EVENT_PRIMARYUP\r\n\t\t\t;mouse was pressed, lets check to see if they choose a new item in list\r\n\t\t\t;check which list item is highlighted\r\n\t\t\t$tempList = GUICtrlRead($List1)\r\n\t\t\t;see if this is new item chosen or just a click somewhere on the prog\r\n\t\t\tif $tempList &lt;&gt; $ListLocation Then\r\n\t\t\t\t;change, update everything\r\n\t\t\t\t;set list location to the temp value\r\n\t\t\t\t$ListLocation = $tempList\r\n\t\t\t\t;set all our gui values\r\n\t\t\t\tGUICtrlSetData($InDescription,stringleft($ListLocation,StringInStr($ListLocation,&quot;,&quot;) - 1))\r\n\t\t\t\tGUICtrlSetData($IPAddress1, StringMid($ListLocation, StringInStr($ListLocation,&quot;,&quot;) + 1, StringInStr($ListLocation,&quot;,&quot;, 0, 2) - StringInStr($ListLocation,&quot;,&quot;) - 1))\r\n\t\t\t\tGUICtrlSetData($InUsername, StringMid($ListLocation, StringInStr($ListLocation,&quot;,&quot;, 0, 2) + 1, StringInStr($ListLocation,&quot;,&quot;, 0, 3) - StringInStr($ListLocation,&quot;,&quot;, 0, 2) - 1))\r\n\t\t\t\tGUICtrlSetData($InPassword, StringMid($ListLocation, StringInStr($ListLocation,&quot;,&quot;, 0, 3) + 1))\r\n\t\t\tEndIf\r\n\t\tCase $GUI_EVENT_CLOSE\r\n\t\t\tExit\r\n\t\tCase $BtnUpdate\r\n\t\t\t;update existing or commit the new one\r\n\t\t\tif $IPAddress1 == &quot;0.0.0.0&quot; Then\r\n\t\t\t\tMsgBox(0,&quot;nope&quot;, &quot;Must enter an IP address&quot;)\r\n\t\t\telseif $InUsername == &quot;&quot; Then\r\n\t\t\t\tMsgBox(0,&quot;nope&quot;, &quot;Must enter a username&quot;)\r\n\t\t\tElse\r\n\t\t\t\t;lets rock it\r\n\t\t\t\t$new = 1\r\n\t\t\t\t;where in the loop are we\r\n\t\t\t\t$updateNum = 0\r\n\t\t\t\t;check to see if it exists\r\n\t\t\t\tfor $y = 1 to $aConfig[0]\r\n\t\t\t\t\t;check if the IP exists\r\n\t\t\t\t\tif StringInStr($aConfig[$y], GUICtrlRead($IPAddress1)) &gt; 0 Then\r\n\t\t\t\t\t\t;we have a match\r\n\t\t\t\t\t\t$new = 0\r\n\t\t\t\t\t\t$updateNum = $y\r\n\t\t\t\t\tEndIf\r\n\t\t\t\tNext\r\n\t\t\t\t;ready to rock, save it\r\n\t\t\t\tif $new = 1 Then\r\n\t\t\t\t\t;new one\r\n\t\t\t\t\t;add to end of the array\r\n\t\t\t\t\t_ArrayAdd($aConfig, GUICtrlRead($InDescription) &amp; &quot;,&quot; &amp; GUICtrlRead($IPAddress1) &amp; &quot;,&quot; &amp; GUICtrlRead($InUsername) &amp; &quot;,&quot; &amp; GUICtrlRead($InPassword))\r\n\t\t\t\t\t;sort our array\r\n\t\t\t\t\t_ArraySort($aConfig,0,1)\r\n\t\t\t\t\t;write the file\r\n\t\t\t\t\t_FileWriteFromArray(@ScriptDir &amp; &quot;\\backupconfig.txt&quot;,$aConfig,1)\r\n\t\t\t\t\t;run plink to accept cert\r\n\t\t\t\t\tRun(@ComSpec &amp; &quot; \/c &quot; &amp; FileGetShortName(@ScriptDir) &amp; &#039;\\plink.exe -ssh &#039; &amp; GUICtrlRead($IPAddress1))\r\n\t\t\t\t\t;load the list again\r\n\t\t\t\t\t_LoadConfig()\r\n\t\t\t\tElse\r\n\t\t\t\t\t;update\r\n\t\t\t\t\t;set existing value\r\n\t\t\t\t\t$aConfig[$updateNum] = GUICtrlRead($InDescription) &amp; &quot;,&quot; &amp; GUICtrlRead($IPAddress1) &amp; &quot;,&quot; &amp; GUICtrlRead($InUsername) &amp; &quot;,&quot; &amp; GUICtrlRead($InPassword)\r\n\t\t\t\t\t;sort array\r\n\t\t\t\t\t_ArraySort($aConfig,0,1)\r\n\t\t\t\t\t;write the array to file\r\n\t\t\t\t\t_FileWriteFromArray(@ScriptDir &amp; &quot;\\backupconfig.txt&quot;,$aConfig,1)\r\n\t\t\t\t\t;reload list\r\n\t\t\t\t\t_LoadConfig()\r\n\t\t\t\tEndIf\r\n\t\t\tEndIf\r\n\t\tCase $BtnDelete\r\n\t\t\t;delete an existing entry\r\n\t\t\t$sure = MsgBox(4, &quot;Delete Record?&quot;, &quot;Are you sure you want to delete &quot; &amp; GUICtrlRead($InDescription) &amp; &quot;?&quot;)\r\n\t\t\tif $sure == 6 Then\r\n\t\t\t\t;delete it\r\n\t\t\t\t$updateNum = 0\r\n\t\t\t\t;find the array #\r\n\t\t\t\tfor $y = 1 to $aConfig[0]\r\n\t\t\t\t\t;check if the IP exists\r\n\t\t\t\t\tif StringInStr($aConfig[$y], GUICtrlRead($IPAddress1)) &gt; 0 Then\r\n\t\t\t\t\t\t;we have a match\r\n\t\t\t\t\t\t$updateNum = $y\r\n\t\t\t\t\tEndIf\r\n\t\t\t\tNext\r\n\t\t\t\t;delete the entry\r\n\t\t\t\t_ArrayDelete($aConfig,$updateNum)\r\n\t\t\t\t;write it to file\r\n\t\t\t\t_FileWriteFromArray(@ScriptDir &amp; &quot;\\backupconfig.txt&quot;,$aConfig,1)\r\n\t\t\t\t;reload list\r\n\t\t\t\t_LoadConfig()\r\n\t\t\tEndIf\r\n\t\tCase $Form1\r\n\tEndSwitch\r\n\t;little sleep to lower CPU\r\n\tsleep(30)\r\nWEnd\r\n\r\nFunc _LoadConfig()\r\nGUICtrlSetData($List1, &quot;&quot;)\r\nIf Not _FileReadToArray(@ScriptDir &amp; &quot;\\backupconfig.txt&quot;,$aConfig) Then\r\nElse\r\n\t;sorty array\r\n\t_ArraySort($aConfig,0,1)\r\n\t;load list\r\n\tFor $x = 1 to $aConfig[0]\r\n\t\tGUICtrlSetData($List1, $aConfig[$x])\r\n\tNext\r\nEndIf\r\nEndFunc\r\n\r\n\r\nFunc _BackupAll()\r\n\t;pull config file\r\n\tIf Not _FileReadToArray(@ScriptDir &amp; &quot;\\backupconfig.txt&quot;,$aConfig) Then\r\n\t\tExit\r\n\tEndIf\r\n\t;create store folder\r\n\tDirCreate(@ScriptDir &amp; &quot;\\&quot; &amp; @YEAR)\r\n\tDirCreate(@ScriptDir &amp; &quot;\\&quot; &amp; @YEAR &amp; &quot;\\&quot; &amp; @MON)\r\n\t;walk the list and call plink\r\n\tfor $x = 1 to $aConfig[0]\r\n\t\t;backup the config\r\n\t\t$CLIusername = StringMid($aConfig[$x], StringInStr($aConfig[$x],&quot;,&quot;, 0, 2) + 1, StringInStr($aConfig[$x],&quot;,&quot;, 0, 3) - StringInStr($aConfig[$x],&quot;,&quot;, 0, 2) - 1)\r\n\t\t$CLIpassword = StringMid($aConfig[$x], StringInStr($aConfig[$x],&quot;,&quot;, 0, 3) + 1)\r\n\t\t$CLIip = StringMid($aConfig[$x], StringInStr($aConfig[$x],&quot;,&quot;) + 1, StringInStr($aConfig[$x],&quot;,&quot;, 0, 2) - StringInStr($aConfig[$x],&quot;,&quot;) - 1)\r\n\t\t$CLIfile = FileGetShortName(@ScriptDir) &amp; &quot;\\&quot; &amp; @YEAR &amp; &quot;\\&quot; &amp; @MON &amp; &quot;\\&quot; &amp; StringReplace(stringleft($aConfig[$x],StringInStr($aConfig[$x],&quot;,&quot;) - 1), &quot; &quot;, &quot;-&quot;) &amp; &quot;-&quot; &amp; StringReplace($CLIip, &quot;.&quot;, &quot;-&quot;) &amp; &quot;-&quot; &amp; @MON &amp; &quot;-&quot; &amp; @MDAY &amp; &quot;.txt&quot;\r\n\t\t;call plink\r\n\t\tRun(@ComSpec &amp; &quot; \/c &quot; &amp; FileGetShortName(@ScriptDir) &amp; &#039;\\plink.exe -ssh -l &#039; &amp; $CLIusername &amp; &#039; -pw &#039; &amp; $CLIpassword &amp; &#039; -m &#039; &amp; FileGetShortName(@ScriptDir) &amp; &#039;\\commands.txt &#039; &amp; $CLIip &amp; &#039; &gt; &#039; &amp; $CLIfile, &quot;&quot;, @SW_HIDE)\r\n\tNext\r\nEndFunc\r\n\r\nFunc _BackupSingle()\r\n\t;create backup dir\r\n\tDirCreate(@ScriptDir &amp; &quot;\\&quot; &amp; @YEAR)\r\n\tDirCreate(@ScriptDir &amp; &quot;\\&quot; &amp; @YEAR &amp; &quot;\\&quot; &amp; @MON)\r\n\t$CLIusername = GUICtrlRead($InUsername)\r\n\t$CLIpassword = GUICtrlRead($InPassword)\r\n\t$CLIip = GUICtrlRead($IPAddress1)\r\n\t$CLIfile = FileGetShortName(@ScriptDir) &amp; &quot;\\&quot; &amp; @YEAR &amp; &quot;\\&quot; &amp; @MON &amp; &quot;\\&quot; &amp; StringReplace(GUICtrlRead($InDescription), &quot; &quot;, &quot;-&quot;) &amp; &quot;-&quot; &amp; StringReplace($CLIip, &quot;.&quot;, &quot;-&quot;) &amp; &quot;-&quot; &amp; @MON &amp; &quot;-&quot; &amp; @MDAY &amp; &quot;.txt&quot;\r\n\t;run plink\r\n\tRun(@ComSpec &amp; &quot; \/c &quot; &amp; FileGetShortName(@ScriptDir) &amp; &#039;\\plink.exe -ssh -l &#039; &amp; $CLIusername &amp; &#039; -pw &#039; &amp; $CLIpassword &amp; &#039; -m &#039; &amp; FileGetShortName(@ScriptDir) &amp; &#039;\\commands.txt &#039; &amp; $CLIip &amp; &#039; &gt; &#039; &amp; $CLIfile, &quot;&quot;, @SW_HIDE)\r\nEndFunc<\/code><\/pre>\n<p>Another note, the config file is in plain text.  The config files are pulled in plain text, so it is a bit of a moot point \ud83d\ude09<\/p>\n<p>This was written and tested on Windows XP, and I&#8217;m working on testing other versions.  I&#8217;ve also tested on 64 bit Windows Vista, and it works a treat.  Be sure you make an allowance in your firewall for plink to access TCP 22 outbound.<\/p>\n<p>Anyway, I just finished this guy, so give it a go and let me know of any bugs or updates you guys want.<\/p>\n<p>**I just updated the code to create a YEARFOLDER\/MONTHFOLDER, so the backups will be separated by months.**<\/p>\n<p>If you like the program, let me know in the comments section!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>So what this little autoit script does is SSH(using plink) into your Mikrotiks and issue the export command. It has a GUI to add\u2026<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,6,7],"tags":[],"class_list":["post-1264","post","type-post","status-publish","format-standard","hentry","category-autoit","category-mikrotik","category-programmingscripting"],"_links":{"self":[{"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/posts\/1264","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/gregsowell.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1264"}],"version-history":[{"count":20,"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/posts\/1264\/revisions"}],"predecessor-version":[{"id":1282,"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/posts\/1264\/revisions\/1282"}],"wp:attachment":[{"href":"https:\/\/gregsowell.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1264"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gregsowell.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1264"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gregsowell.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1264"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}