Automated Mikrotik Backups From Windows Securely
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 all of your routers, and you use the windows scheduler to run the program to do automated backups.
It creates a sub folder in the script directory. It then creates a text file in the format
SCRIPT-DIRECTORY\YEAR\DESCRIPTION-IP ADDRESS-MONTH-DAY.TXT
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.
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.
If you want to delete an entry, highlight it and click delete.
There is a caveat with plink. When hitting a device via ssh for the first time it requires you to accept the host key…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.
Schedule it to run automatically
*NOTE* Whatever user account on the windows machine you accept the host keys with, is the account you need to run the scheduled task as!
Schedule a windows task to run the MikrotikBackup.exe program, and then add anything after the program name like the following:
c:\scripts\MikrotikBackup.exe -GregRocks
Adding anything after the executable makes it run silently and backup all routers.
You can download the executable from here: MikrotikBackup (3978 downloads) .
Here’s the autoit code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <GuiIPAddress.au3> #include <GUIListBox.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #include <File.au3> #include <Array.au3> FileInstall("C:\Documents and Settings\greg\Desktop\autoit\mikrotikBackup\plink.exe", @ScriptDir & "\plink.exe") Dim $aConfig ;check if they are running backup version if $CmdLine[0] > 0 Then ;they are running it from the command line ;pull config file _BackupAll() ;exit once done Exit EndIf ;gui goodness #Region ### START Koda GUI section ### Form=C:\Documents and Settings\greg\Desktop\autoit\mikrotikBackup\MikrotikBackup.kxf $Form1 = GUICreate("GregSowell.com Mikrotik Backup", 497, 446, 192, 114) $List1 = GUICtrlCreateList("", 16, 16, 273, 422) $BtnDelete = GUICtrlCreateButton("Delete", 312, 406, 73, 25, $WS_GROUP) $BtnAll = GUICtrlCreateButton("Backup All", 312, 283, 73, 25, $WS_GROUP) $BtnSingle = GUICtrlCreateButton("Backup Single", 312, 321, 73, 25, $WS_GROUP) $IPAddress1 = GUICtrlCreateInput("0.0.0.0", 312, 32, 129, 17) $InDescription = GUICtrlCreateInput("", 312, 88, 169, 21) $Label1 = GUICtrlCreateLabel("IP Address", 312, 16, 55, 17) $Label2 = GUICtrlCreateLabel("Description", 312, 65, 57, 17) $Label3 = GUICtrlCreateLabel("Username", 312, 129, 52, 17) $Label4 = GUICtrlCreateLabel("Password", 312, 190, 50, 17) $InUsername = GUICtrlCreateInput("admin", 312, 147, 169, 21) $InPassword = GUICtrlCreateInput("", 312, 207, 169, 21);, BitOR($ES_PASSWORD,$ES_AUTOHSCROLL)) $BtnUpdate = GUICtrlCreateButton("&Add/Update", 312, 246, 73, 25, $WS_GROUP) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### $ListLocation = 1 ;check for config file if not FileExists(@ScriptDir & "\backupconfig.txt") Then ;doesn't exist, so create our dummy file $fConfig = FileOpen(@ScriptDir & "\backupconfig.txt", 1) FileWriteLine($fConfig, "demo delete me,1.1.1.1,delete,me" & @CRLF) FileClose($fConfig) EndIf $fCommand = FileOpen(@ScriptDir & "\commands.txt", 2) FileWriteLine($fCommand, "export" & @CRLF) FileClose($fCommand) ;load in the config file _LoadConfig() ;main running loop While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $BtnAll ;backup all of them _BackupAll() Case $BtnSingle ;backup single guy _BackupSingle() case $GUI_EVENT_PRIMARYUP ;mouse was pressed, lets check to see if they choose a new item in list ;check which list item is highlighted $tempList = GUICtrlRead($List1) ;see if this is new item chosen or just a click somewhere on the prog if $tempList <> $ListLocation Then ;change, update everything ;set list location to the temp value $ListLocation = $tempList ;set all our gui values GUICtrlSetData($InDescription,stringleft($ListLocation,StringInStr($ListLocation,",") - 1)) GUICtrlSetData($IPAddress1, StringMid($ListLocation, StringInStr($ListLocation,",") + 1, StringInStr($ListLocation,",", 0, 2) - StringInStr($ListLocation,",") - 1)) GUICtrlSetData($InUsername, StringMid($ListLocation, StringInStr($ListLocation,",", 0, 2) + 1, StringInStr($ListLocation,",", 0, 3) - StringInStr($ListLocation,",", 0, 2) - 1)) GUICtrlSetData($InPassword, StringMid($ListLocation, StringInStr($ListLocation,",", 0, 3) + 1)) EndIf Case $GUI_EVENT_CLOSE Exit Case $BtnUpdate ;update existing or commit the new one if $IPAddress1 == "0.0.0.0" Then MsgBox(0,"nope", "Must enter an IP address") elseif $InUsername == "" Then MsgBox(0,"nope", "Must enter a username") Else ;lets rock it $new = 1 ;where in the loop are we $updateNum = 0 ;check to see if it exists for $y = 1 to $aConfig[0] ;check if the IP exists if StringInStr($aConfig[$y], GUICtrlRead($IPAddress1)) > 0 Then ;we have a match $new = 0 $updateNum = $y EndIf Next ;ready to rock, save it if $new = 1 Then ;new one ;add to end of the array _ArrayAdd($aConfig, GUICtrlRead($InDescription) & "," & GUICtrlRead($IPAddress1) & "," & GUICtrlRead($InUsername) & "," & GUICtrlRead($InPassword)) ;sort our array _ArraySort($aConfig,0,1) ;write the file _FileWriteFromArray(@ScriptDir & "\backupconfig.txt",$aConfig,1) ;run plink to accept cert Run(@ComSpec & " /c " & FileGetShortName(@ScriptDir) & '\plink.exe -ssh ' & GUICtrlRead($IPAddress1)) ;load the list again _LoadConfig() Else ;update ;set existing value $aConfig[$updateNum] = GUICtrlRead($InDescription) & "," & GUICtrlRead($IPAddress1) & "," & GUICtrlRead($InUsername) & "," & GUICtrlRead($InPassword) ;sort array _ArraySort($aConfig,0,1) ;write the array to file _FileWriteFromArray(@ScriptDir & "\backupconfig.txt",$aConfig,1) ;reload list _LoadConfig() EndIf EndIf Case $BtnDelete ;delete an existing entry $sure = MsgBox(4, "Delete Record?", "Are you sure you want to delete " & GUICtrlRead($InDescription) & "?") if $sure == 6 Then ;delete it $updateNum = 0 ;find the array # for $y = 1 to $aConfig[0] ;check if the IP exists if StringInStr($aConfig[$y], GUICtrlRead($IPAddress1)) > 0 Then ;we have a match $updateNum = $y EndIf Next ;delete the entry _ArrayDelete($aConfig,$updateNum) ;write it to file _FileWriteFromArray(@ScriptDir & "\backupconfig.txt",$aConfig,1) ;reload list _LoadConfig() EndIf Case $Form1 EndSwitch ;little sleep to lower CPU sleep(30) WEnd Func _LoadConfig() GUICtrlSetData($List1, "") If Not _FileReadToArray(@ScriptDir & "\backupconfig.txt",$aConfig) Then Else ;sorty array _ArraySort($aConfig,0,1) ;load list For $x = 1 to $aConfig[0] GUICtrlSetData($List1, $aConfig[$x]) Next EndIf EndFunc Func _BackupAll() ;pull config file If Not _FileReadToArray(@ScriptDir & "\backupconfig.txt",$aConfig) Then Exit EndIf ;create store folder DirCreate(@ScriptDir & "\" & @YEAR) DirCreate(@ScriptDir & "\" & @YEAR & "\" & @MON) ;walk the list and call plink for $x = 1 to $aConfig[0] ;backup the config $CLIusername = StringMid($aConfig[$x], StringInStr($aConfig[$x],",", 0, 2) + 1, StringInStr($aConfig[$x],",", 0, 3) - StringInStr($aConfig[$x],",", 0, 2) - 1) $CLIpassword = StringMid($aConfig[$x], StringInStr($aConfig[$x],",", 0, 3) + 1) $CLIip = StringMid($aConfig[$x], StringInStr($aConfig[$x],",") + 1, StringInStr($aConfig[$x],",", 0, 2) - StringInStr($aConfig[$x],",") - 1) $CLIfile = FileGetShortName(@ScriptDir) & "\" & @YEAR & "\" & @MON & "\" & StringReplace(stringleft($aConfig[$x],StringInStr($aConfig[$x],",") - 1), " ", "-") & "-" & StringReplace($CLIip, ".", "-") & "-" & @MON & "-" & @MDAY & ".txt" ;call plink Run(@ComSpec & " /c " & FileGetShortName(@ScriptDir) & '\plink.exe -ssh -l ' & $CLIusername & ' -pw ' & $CLIpassword & ' -m ' & FileGetShortName(@ScriptDir) & '\commands.txt ' & $CLIip & ' > ' & $CLIfile, "", @SW_HIDE) Next EndFunc Func _BackupSingle() ;create backup dir DirCreate(@ScriptDir & "\" & @YEAR) DirCreate(@ScriptDir & "\" & @YEAR & "\" & @MON) $CLIusername = GUICtrlRead($InUsername) $CLIpassword = GUICtrlRead($InPassword) $CLIip = GUICtrlRead($IPAddress1) $CLIfile = FileGetShortName(@ScriptDir) & "\" & @YEAR & "\" & @MON & "\" & StringReplace(GUICtrlRead($InDescription), " ", "-") & "-" & StringReplace($CLIip, ".", "-") & "-" & @MON & "-" & @MDAY & ".txt" ;run plink Run(@ComSpec & " /c " & FileGetShortName(@ScriptDir) & '\plink.exe -ssh -l ' & $CLIusername & ' -pw ' & $CLIpassword & ' -m ' & FileGetShortName(@ScriptDir) & '\commands.txt ' & $CLIip & ' > ' & $CLIfile, "", @SW_HIDE) EndFunc |
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 😉
This was written and tested on Windows XP, and I’m working on testing other versions. I’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.
Anyway, I just finished this guy, so give it a go and let me know of any bugs or updates you guys want.
**I just updated the code to create a YEARFOLDER/MONTHFOLDER, so the backups will be separated by months.**
If you like the program, let me know in the comments section!
Sounds cool! Couldn’t get it to work on Windows7.
1. Add/Update button doesn’t change anything, I assumed it let’s me correct some information in an existing entry?
2. Backup button made the folders, but the text file is empty. SSH works to this router just fine.
By the way, it doesn’t ask me to accept the SSH key. It just silently makes an empty text file, and that’s it.
Bah, Normands, you would roll in using windows 7…hehehe. I tested and built this on windows XP. I’ll try and check with other versions. Plink will need firewall access…TCP port 22 out.
This should pop up a command prompt for you to accept. I’ll try and grab a windows 7 box today to test with.
This reminds me, I should try to get Mikrotik backups working with my routerconfigs plugin for Cacti.
Shouldn’t be too difficult, now that you can totally steal the way I’m doing it…hehe 😛
I already had it working via SSH and issuing an “export” command, I then tried to change it to use the API, which I found to be useless for this type of thing.
Fun fact: You can actually lock up the router by trying to export the config using the API
🙂 I figured as much. Nice tidbit on the API. I’m really only messed with it enough to get it answering some PHP, then quit.
If you get it rocking in the backup plugin, let me know fool.
This solution is hard to implement in real business solution… because plain text, that is (and only maybe is) for “one standing men solution”. 😉
Anyway – now we use it with read-only MT user and limit connection from specify IP.
Upgrade will be greate!
Thank for Your work!
Mocha,
Thanks for dropping me a comment. I think the translation is loosing some thing. It seems that you are using the program, but are unhappy with the plain text nature of the…output…or input? I’m not sure 🙂
I know I need to break down and write it so that you don’t have to manually accept the host key…which I may get around to…eventually. 😉
Greg,
Love the program. it has worked great for us for over 2 months now. Now having a little glitch that I can not figure out.
I have 8 MikroTik routerboards that are being automatically backed up overnight. I just checked the files and noticed that one of them has a 0 kb size file with nothing inside.
I tried deleting and re-entering the information and tried doing an individual backup as well as an all backup, but the same thing happened and the program did not ask for verification this time. I rebooted the routerboard and server that the backup program is running from without any luck. All of the other units are still backing up appropriately.
The program is installed on a Windows 2003 server with all updates from Microsoft.
Joey,
Try opening putty on the server and attempt to SSH in using the same username and password as the program. If you are able to connect, type export. That’s what this program is doing in a nut shell.
That was the problem…someone turned off port 22-ssh in my Services section on that routerboard.
Thanks for the help.
NP, glad to help 🙂
hello, I’m testing the executable, but my computers do not listen mikrotik ssh on port 22, but in 2076, there is no way that the backup script to run the same?
@Ariel
You can grab autoit and change the command line call to adjust for the new port.
Very nice little “guy” easy to implement. good work!!!!
Greg, please advice since it work fine on my Win2K3 but not for 2K8 …
Tx
@Bagus
I don’t have a 2k8 machine to test with right now.