Skip to content
Dec 21 / Greg

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

The program in all it's glory...;)

The program in all it's glory...;)

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 (3055).

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!

19 Comments

leave a comment
  1. N.R. / Dec 21 2009

    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.

  2. N.R. / Dec 21 2009

    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.

  3. Greg / Dec 21 2009

    N.R. :

    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.

    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.

  4. Greg / Dec 21 2009

    N.R. :

    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.

    This should pop up a command prompt for you to accept. I’ll try and grab a windows 7 box today to test with.

  5. Jimmy / Dec 21 2009

    This reminds me, I should try to get Mikrotik backups working with my routerconfigs plugin for Cacti.

  6. Greg / Dec 21 2009

    Jimmy :

    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 😛

  7. Jimmy / Dec 21 2009

    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

  8. Greg / Dec 21 2009

    Jimmy :

    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.

  9. mocha / Feb 17 2010

    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!

  10. Greg / Feb 17 2010

    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. 😉

  11. Joey / Sep 24 2010

    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.

  12. Greg / Sep 24 2010

    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.

  13. Joey / Sep 24 2010

    That was the problem…someone turned off port 22-ssh in my Services section on that routerboard.

    Thanks for the help.

  14. Greg / Sep 24 2010

    NP, glad to help 🙂

  15. Ariel / Mar 23 2011

    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?

  16. Greg / Mar 23 2011

    @Ariel
    You can grab autoit and change the command line call to adjust for the new port.

  17. Kent / Jul 18 2011

    Very nice little “guy” easy to implement. good work!!!!

  18. Bagus / Mar 26 2012

    Greg, please advice since it work fine on my Win2K3 but not for 2K8 …

    Tx

  19. Greg / Mar 26 2012

    @Bagus
    I don’t have a 2k8 machine to test with right now.

Leave a Comment

*