├── .gitignore ├── README.md ├── images └── bookcover.png ├── screenshots ├── chapter1 │ ├── Figure1-1.png │ ├── Figure1-10.png │ ├── Figure1-11.png │ ├── Figure1-12.png │ ├── Figure1-13.png │ ├── Figure1-14.png │ ├── Figure1-15.png │ ├── Figure1-16.png │ ├── Figure1-17.png │ ├── Figure1-18.png │ ├── Figure1-19.png │ ├── Figure1-2.png │ ├── Figure1-20.png │ ├── Figure1-21.png │ ├── Figure1-3.png │ ├── Figure1-4.png │ ├── Figure1-5.png │ ├── Figure1-6.png │ ├── Figure1-7.png │ ├── Figure1-8.png │ └── Figure1-9.png ├── chapter2 │ ├── Figure2-1.png │ ├── Figure2-10.png │ ├── Figure2-11.png │ ├── Figure2-12.png │ ├── Figure2-13.png │ ├── Figure2-14.png │ ├── Figure2-15.png │ ├── Figure2-16.png │ ├── Figure2-17.png │ ├── Figure2-2.png │ ├── Figure2-3.png │ ├── Figure2-4.png │ ├── Figure2-5.png │ ├── Figure2-6.png │ ├── Figure2-7.png │ ├── Figure2-8.png │ └── Figure2-9.png └── chapter5 │ └── Figure5-1.png └── scripts ├── v6 ├── ch1-01-board-type.rsc ├── ch1-02-get-board-arch.rsc ├── ch10-01-bad-script.rsc ├── ch10-02-bad-script.rsc ├── ch10-03-bad-script.rsc ├── ch10-04-bad-script.rsc ├── ch10-05-error_check.rsc ├── ch10-06-error_check.rsc ├── ch10-07-bad-script.rsc ├── ch10-08-bad-script.rsc ├── ch10-09-simple-pause.rsc ├── ch10-10-add-remove-vlans.rsc ├── ch10-11-add-remove-vlans.rsc ├── ch10-12-add-remove-vlans.rsc ├── ch2-01-hello-world.rsc ├── ch4-01-bad-ip-data-type.rsc ├── ch5-01-no-semi-colons.rsc ├── ch5-02-semi-colons.rsc ├── ch5-03-long-line.rsc ├── ch5-04-no-indentation.rsc ├── ch5-05-indentation.rsc ├── ch6-01-variable-value-test.rsc ├── ch6-02-undeclared-variable.rsc ├── ch6-03-global-scope.rsc ├── ch6-04-local-scope.rsc ├── ch6-05-local-scope.rsc ├── ch6-06-local-scope.rsc ├── ch6-07-variable-types.rsc ├── ch6-08-local-vars.rsc ├── ch6-09-local-vars2.rsc ├── ch6-10-global-vars.rsc ├── ch6-11-global-vars2.rsc ├── ch6-12-global-vars3.rsc ├── ch7-01-basic-if.rsc ├── ch7-02-basic-if.rsc ├── ch7-03-if-else.rsc ├── ch7-04-if-else-vars.rsc ├── ch7-05-if-else-vars2.rsc ├── ch7-06-if-multiple-conditions.rsc ├── ch7-07-nested-if-statements.rsc ├── ch7-08-if-else-binary.rsc ├── ch7-09-if-binary-simplified.rsc ├── ch8-01-for-basic.rsc ├── ch8-02-for-check-web.rsc ├── ch8-03-for-create-vlan.rsc ├── ch8-04-foreach-web.rsc ├── ch8-05-foreach-kv.rsc ├── ch8-06-while-infinite.rsc ├── ch8-07-while-with-exit.rsc ├── ch8-08-while-timer.rsc ├── ch8-09-while-alt-form.rsc ├── ch9-01-mac-fixer.rsc ├── ch9-02-mutiple-args-simple.rsc ├── ch9-03-mutiple-args-array.rsc ├── ch9-04-create-global-func.rsc ├── ch9-05-use-global-func.rsc ├── ch9-06-str-funcs-mod.rsc └── ch9-07-use-str-module.rsc └── v7 ├── ch1-01-board-type.rsc ├── ch1-02-get-board-arch.rsc ├── ch10-01-bad-script.rsc ├── ch10-02-bad-script.rsc ├── ch10-03-bad-script.rsc ├── ch10-04-bad-script.rsc ├── ch10-05-error_check.rsc ├── ch10-06-error_check.rsc ├── ch10-07-bad-script.rsc ├── ch10-08-bad-script.rsc ├── ch10-09-simple-pause.rsc ├── ch10-10-add-remove-vlans.rsc ├── ch10-11-add-remove-vlans.rsc ├── ch10-12-add-remove-vlans.rsc ├── ch2-01-hello-world.rsc ├── ch4-01-bad-ip-data-type.rsc ├── ch5-01-no-semi-colons.rsc ├── ch5-02-semi-colons.rsc ├── ch5-03-long-line.rsc ├── ch5-04-no-indentation.rsc ├── ch5-05-indentation.rsc ├── ch6-01-variable-value-test.rsc ├── ch6-02-undeclared-variable.rsc ├── ch6-03-global-scope.rsc ├── ch6-04-local-scope.rsc ├── ch6-05-local-scope.rsc ├── ch6-06-local-scope.rsc ├── ch6-07-variable-types.rsc ├── ch6-08-local-vars.rsc ├── ch6-09-local-vars2.rsc ├── ch6-10-global-vars.rsc ├── ch6-11-global-vars2.rsc ├── ch6-12-global-vars3.rsc ├── ch7-01-basic-if.rsc ├── ch7-02-basic-if.rsc ├── ch7-03-if-else.rsc ├── ch7-04-if-else-vars.rsc ├── ch7-05-if-else-vars2.rsc ├── ch7-06-if-multiple-conditions.rsc ├── ch7-07-nested-if-statements.rsc ├── ch7-08-if-else-binary.rsc ├── ch7-09-if-binary-simplified.rsc ├── ch8-01-for-basic.rsc ├── ch8-02-for-check-web.rsc ├── ch8-03-for-create-vlan.rsc ├── ch8-04-foreach-web.rsc ├── ch8-05-foreach-kv.rsc ├── ch8-06-while-infinite.rsc ├── ch8-07-while-with-exit.rsc ├── ch8-08-while-timer.rsc ├── ch8-09-while-alt-form.rsc ├── ch9-01-mac-fixer.rsc ├── ch9-02-mutiple-args-simple.rsc ├── ch9-03-mutiple-args-array.rsc ├── ch9-04-create-global-func.rsc ├── ch9-05-use-global-func.rsc ├── ch9-06-str-funcs-mod.rsc └── ch9-07-use-str-module.rsc /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mikrotik Scripting 2 | Welcome to the Mikrotik Scripting book code and image repository. 3 | 4 | All code examples from the book may be found here: 5 | 6 | - [V6](scripts/v6) 7 | - [V7](scripts/v7) 8 | 9 | Screenshots from the book may be found here: [images](screenshots/) 10 | 11 | A zipped archive of all script & screenshot files may be downloaded from [here](https://mikrotikscripting.com/downloads/mikrotik_scripting.zip). 12 | 13 | You can visit the book's web site at: [https://MikrotikScripting.com](https://mikrotikscripting.com) 14 | 15 | ![Bookcover](images/bookcover.png) 16 | -------------------------------------------------------------------------------- /images/bookcover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/images/bookcover.png -------------------------------------------------------------------------------- /screenshots/chapter1/Figure1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter1/Figure1-1.png -------------------------------------------------------------------------------- /screenshots/chapter1/Figure1-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter1/Figure1-10.png -------------------------------------------------------------------------------- /screenshots/chapter1/Figure1-11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter1/Figure1-11.png -------------------------------------------------------------------------------- /screenshots/chapter1/Figure1-12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter1/Figure1-12.png -------------------------------------------------------------------------------- /screenshots/chapter1/Figure1-13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter1/Figure1-13.png -------------------------------------------------------------------------------- /screenshots/chapter1/Figure1-14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter1/Figure1-14.png -------------------------------------------------------------------------------- /screenshots/chapter1/Figure1-15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter1/Figure1-15.png -------------------------------------------------------------------------------- /screenshots/chapter1/Figure1-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter1/Figure1-16.png -------------------------------------------------------------------------------- /screenshots/chapter1/Figure1-17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter1/Figure1-17.png -------------------------------------------------------------------------------- /screenshots/chapter1/Figure1-18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter1/Figure1-18.png -------------------------------------------------------------------------------- /screenshots/chapter1/Figure1-19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter1/Figure1-19.png -------------------------------------------------------------------------------- /screenshots/chapter1/Figure1-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter1/Figure1-2.png -------------------------------------------------------------------------------- /screenshots/chapter1/Figure1-20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter1/Figure1-20.png -------------------------------------------------------------------------------- /screenshots/chapter1/Figure1-21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter1/Figure1-21.png -------------------------------------------------------------------------------- /screenshots/chapter1/Figure1-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter1/Figure1-3.png -------------------------------------------------------------------------------- /screenshots/chapter1/Figure1-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter1/Figure1-4.png -------------------------------------------------------------------------------- /screenshots/chapter1/Figure1-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter1/Figure1-5.png -------------------------------------------------------------------------------- /screenshots/chapter1/Figure1-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter1/Figure1-6.png -------------------------------------------------------------------------------- /screenshots/chapter1/Figure1-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter1/Figure1-7.png -------------------------------------------------------------------------------- /screenshots/chapter1/Figure1-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter1/Figure1-8.png -------------------------------------------------------------------------------- /screenshots/chapter1/Figure1-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter1/Figure1-9.png -------------------------------------------------------------------------------- /screenshots/chapter2/Figure2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter2/Figure2-1.png -------------------------------------------------------------------------------- /screenshots/chapter2/Figure2-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter2/Figure2-10.png -------------------------------------------------------------------------------- /screenshots/chapter2/Figure2-11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter2/Figure2-11.png -------------------------------------------------------------------------------- /screenshots/chapter2/Figure2-12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter2/Figure2-12.png -------------------------------------------------------------------------------- /screenshots/chapter2/Figure2-13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter2/Figure2-13.png -------------------------------------------------------------------------------- /screenshots/chapter2/Figure2-14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter2/Figure2-14.png -------------------------------------------------------------------------------- /screenshots/chapter2/Figure2-15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter2/Figure2-15.png -------------------------------------------------------------------------------- /screenshots/chapter2/Figure2-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter2/Figure2-16.png -------------------------------------------------------------------------------- /screenshots/chapter2/Figure2-17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter2/Figure2-17.png -------------------------------------------------------------------------------- /screenshots/chapter2/Figure2-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter2/Figure2-2.png -------------------------------------------------------------------------------- /screenshots/chapter2/Figure2-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter2/Figure2-3.png -------------------------------------------------------------------------------- /screenshots/chapter2/Figure2-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter2/Figure2-4.png -------------------------------------------------------------------------------- /screenshots/chapter2/Figure2-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter2/Figure2-5.png -------------------------------------------------------------------------------- /screenshots/chapter2/Figure2-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter2/Figure2-6.png -------------------------------------------------------------------------------- /screenshots/chapter2/Figure2-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter2/Figure2-7.png -------------------------------------------------------------------------------- /screenshots/chapter2/Figure2-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter2/Figure2-8.png -------------------------------------------------------------------------------- /screenshots/chapter2/Figure2-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter2/Figure2-9.png -------------------------------------------------------------------------------- /screenshots/chapter5/Figure5-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wifinigel/MikrotikScripting/cf3f613f3dfeff8b990ea1b30b262377fd867cdc/screenshots/chapter5/Figure5-1.png -------------------------------------------------------------------------------- /scripts/v6/ch1-01-board-type.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch1-01-board-type.rsc 2 | 3 | # A simple script to print your Mikrotik board type 4 | 5 | :local BoardType [/system resource get board]; 6 | :put "Your Mikrotik board type is : $BoardType"; 7 | -------------------------------------------------------------------------------- /scripts/v6/ch1-02-get-board-arch.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch1-02-get-board-arch.rsc 2 | 3 | # A simple script to print your Mikrotik board architecture 4 | 5 | :local ArchitectureName [/system resource get architecture-name]; 6 | :put "Your Mikrotik board architecture is : $ArchitectureName"; -------------------------------------------------------------------------------- /scripts/v6/ch10-01-bad-script.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch10-01-bad-script.rsc 2 | 3 | :local w {"mikrotik.com"; "www.google.com"; "twitter.com"}; 4 | 5 | :foreach s in=$w do={ 6 | :local i [:resolve $s]; 7 | :local p [/ping $i count=3]; 8 | :local u [/tool fetch url=("https://$s") mode=https http-method=get \ 9 | as-value keep-result=no]; 10 | 11 | :put "=========================================="; 12 | :put ("Site: $s"); 13 | :put ("IP Address = $i"); 14 | :put ("Ping success = $p/3"); 15 | :put ("Page d/load duration: " . $u->"duration"); 16 | :put "==========================================="; 17 | } 18 | -------------------------------------------------------------------------------- /scripts/v6/ch10-02-bad-script.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch10-02-bad-script.rsc 2 | # 3 | # A simple script to perform a series of tests on a 4 | # list of web sites. 5 | 6 | # define list of websites to test 7 | :local w {"mikrotik.com"; "www.google.com"; "twitter.com"}; 8 | 9 | # step through each website and perform various tests 10 | :foreach s in=$w do={ 11 | 12 | # try a DNS resolution of this site 13 | :local i [:resolve $s]; 14 | 15 | # try pinging the IP address of this site 16 | :local p [/ping $i count=3]; 17 | 18 | # try fetching the web page of this site 19 | :local u [/tool fetch url=("https://$s") mode=https http-method=get \ 20 | as-value keep-result=no]; 21 | 22 | # print out a summary report for this site 23 | :put "=========================================="; 24 | :put ("Site: $s"); 25 | :put ("IP Address = $i"); 26 | :put ("Ping success = $p/3"); 27 | :put ("Page d/load duration: " . $u->"duration"); 28 | :put "==========================================="; 29 | } 30 | -------------------------------------------------------------------------------- /scripts/v6/ch10-03-bad-script.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch10-03-bad-script.rsc 2 | # 3 | # A simple script to perform a series of tests on a 4 | # list of web sites. 5 | 6 | # define list of websites to test 7 | :local WebSites {"mikrotik.com"; "www.google.com"; "twitter.com"}; 8 | 9 | # step through each website and perform various tests 10 | :foreach SiteName in=$WebSites do={ 11 | 12 | # try a DNS resolution of this site 13 | :local IpAddress [:resolve $SiteName]; 14 | 15 | # try pinging the IP address of this site 16 | :local PingResult [/ping $IpAddress count=3]; 17 | 18 | # try getting the web page of this site 19 | :local UrlFetch [/tool fetch url=("https://$SiteName") mode=https \ 20 | http-method=get as-value keep-result=no]; 21 | 22 | # print out a summary report for this site 23 | :put "=========================================="; 24 | :put ("Site: $SiteName"); 25 | :put ("IP Address = $IpAddress"); 26 | :put ("Ping success = $PingResult/3"); 27 | :put ("Page d/load duration: " . $UrlFetch->"duration"); 28 | :put "==========================================="; 29 | } 30 | -------------------------------------------------------------------------------- /scripts/v6/ch10-04-bad-script.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch10-04-bad-script.rsc 2 | # 3 | # A simple script to perform a series of tests on a 4 | # list of web sites. 5 | 6 | :global Filename "ch10-04-bad-script.rsc"; 7 | 8 | # function to log error message 9 | :global LogMessageFunc do={ 10 | :global Filename; 11 | :local ErrorMessage ("$Filename: $1"); 12 | 13 | :log error $ErrorMessage; 14 | :error $ErrorMessage; 15 | } 16 | 17 | # function to DNS resolve a site name to IP 18 | :global DnsResolveFunc do={ 19 | :local WebSiteName $1; 20 | :global LogMessageFunc; 21 | 22 | # check arg type str of correct length passed 23 | if (([:typeof $WebSiteName]!="str") or \ 24 | ([:len $WebSiteName] < 6)) do={ 25 | $LogMessageFunc ("DnsResolveFunc: arg value $WebSiteName not \ 26 | a valid string!"); 27 | } 28 | 29 | return [:resolve $WebSiteName]; 30 | } 31 | 32 | # function to ping an IP address 3 times 33 | :global PingIpAddressFunc do={ 34 | :local IpAddress $1; 35 | :global LogMessageFunc; 36 | 37 | # check arg type ip is passed 38 | if ([:typeof $IpAddress] != "ip") do={ 39 | $LogMessageFunc ("PingIpAddressFunc: arg value $IpAddress not \ 40 | an IP address!"); 41 | } 42 | 43 | return [/ping $IpAddress count=3]; 44 | } 45 | 46 | # function to return the result of fetching a web page 47 | :global GetWebPageFunc do={ 48 | :local SiteName $1; 49 | :global LogMessageFunc; 50 | 51 | # check arg type str of correct length passed 52 | if (([:typeof $SiteName] != "str") or \ 53 | ([:len $SiteName] < 6)) do={ 54 | $LogMessageFunc ("GetWebPageFunc: arg value $SiteName not a \ 55 | valid string!"); 56 | } 57 | 58 | return [/tool fetch url=("https://$SiteName") mode=https \ 59 | http-method=get as-value keep-result=no]; 60 | } 61 | 62 | ########## 63 | # Main 64 | ########## 65 | 66 | # define list of websites to test 67 | :local WebSites { "mikrotik.com"; "www.google.com"; "twitter.com"}; 68 | 69 | # step through each website and perform various tests 70 | :foreach SiteName in=$WebSites do={ 71 | 72 | # try a DNS resolution of this site 73 | :local IpAddress [$DnsResolveFunc $SiteName]; 74 | 75 | # try pinging the IP address of this site 76 | :local PingResult [$PingIpAddressFunc $IpAddress]; 77 | 78 | # try getting the web page of this site 79 | :local UrlFetch [$GetWebPageFunc $SiteName]; 80 | 81 | # print out a summary report for this site 82 | :put "=========================================="; 83 | :put ("Site: $SiteName"); 84 | :put ("IP Address = $IpAddress"); 85 | :put ("Ping success = $PingResult/3"); 86 | :put ("Page d/load duration: " . $UrlFetch->"duration"); 87 | :put "==========================================="; 88 | } 89 | 90 | # cleanup global namespace 91 | :set LogMessageFunc; 92 | :set DnsResolveFunc; 93 | :set PingIpAddressFunc; 94 | :set GetWebPageFunc; 95 | :set Filename; 96 | -------------------------------------------------------------------------------- /scripts/v6/ch10-05-error_check.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch10-05-error-check.rsc 2 | :local WebSites { "badname1234.com"; "google.com"}; 3 | 4 | :foreach SiteName in=$WebSites do={ 5 | :local SiteIpAddress [:resolve $SiteName]; 6 | :put "Site IP for $SiteName is $SiteIpAddress"; 7 | } 8 | -------------------------------------------------------------------------------- /scripts/v6/ch10-06-error_check.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch10-06-error-check.rsc 2 | :local WebSites { "badname1234.com"; "google.com"}; 3 | :foreach SiteName in=$WebSites do={ 4 | :do { 5 | :local SiteIpAddress [:resolve $SiteName]; 6 | :put "Site IP for $SiteName is $SiteIpAddress"; 7 | } on-error={ 8 | :put "Name lookup failed for $SiteName"; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /scripts/v6/ch10-07-bad-script.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch10-07-bad-script.rsc 2 | # 3 | # A simple script to perform a series of tests on a 4 | # list of web sites. 5 | 6 | :global Filename "ch10-07-bad-script.rsc"; 7 | 8 | # function to log error messages 9 | :global LogMessageFunc do={ 10 | :global Filename; 11 | :local ErrorMessage "$Filename: $1"; 12 | 13 | :log error $ErrorMessage; 14 | :put $ErrorMessage; # print to CLI 15 | } 16 | 17 | # function to DNS resolve a site name to IP 18 | :global DnsResolveFunc do={ 19 | :local WebSiteName $1; 20 | :global LogMessageFunc; 21 | 22 | # check arg type str of correct length passed 23 | :if (([:typeof $WebSiteName] != "str") or \ 24 | ([:len $WebSiteName] < 6)) do={ 25 | $LogMessageFunc ("DnsResolveFunc: arg value $WebSiteName not \ 26 | a valid string!"); 27 | 28 | :return "*** test failed ***"; 29 | } 30 | 31 | # try a name lookup 32 | :do { 33 | return [:resolve $WebSiteName]; 34 | } on-error={ 35 | $LogMessageFunc ("DnsResolveFunc: name resolution failed for \ 36 | site: $WebSiteName!"); 37 | :return "*** test failed ***"; 38 | } 39 | } 40 | 41 | # function to ping an IP address 3 times 42 | :global PingIpAddressFunc do={ 43 | :local IpAddress $1; 44 | :global LogMessageFunc; 45 | 46 | # check arg type ip is passed 47 | :if ([:typeof $IpAddress] != "ip") do={ 48 | $LogMessageFunc ("PingIpAddressFunc: arg value $IpAddress not \ 49 | an IP address!"); 50 | :return "*** test failed ***"; 51 | } 52 | 53 | # try a ping 54 | :do { 55 | return [/ping $IpAddress count=3]; 56 | } on-error={ 57 | $LogMessageFunc ("PingIpAddressFunc: ping test failed: \ 58 | $IpAddress !"); 59 | :return "*** test failed ***"; 60 | } 61 | } 62 | 63 | # function to return the result of fetching a web page 64 | :global GetWebPageFunc do={ 65 | :local SiteName $1; 66 | :global LogMessageFunc; 67 | 68 | # check arg type str of correct length passed 69 | :if (([:typeof $SiteName] != "str") or \ 70 | ([:len $SiteName] < 6)) do={ 71 | $LogMessageFunc ("GetWebPageFunc: arg value $SiteName not a \ 72 | valid string!"); 73 | :return "*** test failed ***"; 74 | } 75 | 76 | # try to get web page 77 | :do { 78 | :return [/tool fetch url=("https://$SiteName") mode=https \ 79 | http-method=get as-value keep-result=no]; 80 | } on-error={ 81 | $LogMessageFunc ("GetWebPageFunc: unable to retrieve site: \ 82 | $SiteName !"); 83 | :return { "duration"="*** test failed ***" } 84 | } 85 | } 86 | 87 | ########## 88 | # Main 89 | ########## 90 | 91 | # define list of websites to test 92 | :local WebSites { "badsite1234.com"; "www.google.com"; "twitter.com"}; 93 | 94 | # step through each website and perform various tests 95 | :foreach SiteName in=$WebSites do={ 96 | 97 | # try a DNS resolution of this site 98 | :local IpAddress [$DnsResolveFunc $SiteName]; 99 | 100 | # try pinging the IP address of this site 101 | :local PingResult [$PingIpAddressFunc $IpAddress]; 102 | 103 | # try getting the web page of this site 104 | :local UrlFetch [$GetWebPageFunc $SiteName]; 105 | 106 | # print out a summary report for this site 107 | :put "=========================================="; 108 | :put ("Site: $SiteName"); 109 | :put ("IP Address = $IpAddress"); 110 | :put ("Ping success = $PingResult/3"); 111 | :put ("Page d/load duration: " . $UrlFetch->"duration"); 112 | :put "==========================================="; 113 | } 114 | 115 | # cleanup global namespace 116 | :set LogMessageFunc; 117 | :set DnsResolveFunc; 118 | :set PingIpAddressFunc; 119 | :set GetWebPageFunc; 120 | :set Filename; 121 | -------------------------------------------------------------------------------- /scripts/v6/ch10-08-bad-script.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch10-08-bad-script.rsc 2 | # 3 | # A simple script to perform a series of tests on a 4 | # list of web sites. 5 | 6 | :global Filename "ch10-08-bad-script.rsc"; 7 | 8 | # set DEBUG to "true" for script debugging output, 9 | # "false" for normal operation 10 | :global DEBUG false; 11 | 12 | # debug function 13 | :global DebugFunc do={ 14 | :global DEBUG; 15 | :if ($DEBUG) do={ :put "**Debug: $1"; } 16 | } 17 | 18 | # function to log error messages 19 | :global LogMessageFunc do={ 20 | :global Filename; 21 | :local ErrorMessage "$Filename: $1"; 22 | 23 | :log error $ErrorMessage; 24 | :put $ErrorMessage; # print to CLI 25 | } 26 | 27 | # function to DNS resolve a site name to IP 28 | :global DnsResolveFunc do={ 29 | :local WebSiteName $1; 30 | :global LogMessageFunc; 31 | :global DebugFunc; 32 | 33 | $DebugFunc "Entering DnsResolveFunc"; 34 | $DebugFunc ("Arg passed to func: $WebSiteName"); 35 | 36 | # check arg type str of correct length passed 37 | $DebugFunc "Checking arg data type is correct"; 38 | 39 | :if (([:typeof $WebSiteName] != "str") or \ 40 | ([:len $WebSiteName] < 6)) do={ 41 | :local ErrorMsg "DnsResolveFunc: arg value $WebSiteName \ 42 | not a valid string!"; 43 | $LogMessageFunc $ErrorMsg; 44 | $DebugFunc $ErrorMsg; 45 | :return "*** test failed ***"; 46 | } else={ 47 | $DebugFunc "Data type looks good"; 48 | } 49 | 50 | :do { 51 | $DebugFunc "Looking up IP of site name..."; 52 | :local SiteIpAddr [:resolve $WebSiteName]; 53 | $DebugFunc $SiteIpAddr; 54 | :return $SiteIpAddr; 55 | } on-error={ 56 | $DebugFunc "DNS lookup failed!"; 57 | $LogMessageFunc ("DnsResolveFunc: name resolution failed for \ 58 | site: $WebSiteName!"); 59 | :return "*** test failed ***"; 60 | } 61 | } 62 | 63 | # function to ping an IP address 3 times 64 | :global PingIpAddressFunc do={ 65 | :local IpAddress $1; 66 | :global LogMessageFunc; 67 | 68 | # check arg type ip is passed 69 | :if ([:typeof $IpAddress] != "ip") do={ 70 | $LogMessageFunc ("PingIpAddressFunc: arg value $IpAddress not \ 71 | an IP address!"); 72 | :return "*** test failed ***"; 73 | } 74 | 75 | :do { 76 | return [/ping $IpAddress count=3]; 77 | } on-error { 78 | $LogMessageFunc ("PingIpAddressFunc: ping test to IP address \ 79 | failed: $IpAddress !"); 80 | :return "*** test failed ***"; 81 | } 82 | } 83 | 84 | # function to return the result of fetching a web page 85 | :global GetWebPageFunc do={ 86 | :local SiteName $1; 87 | :global LogMessageFunc; 88 | 89 | # check arg type str of correct length passed 90 | if (([:typeof $SiteName] != "str") or \ 91 | ([:len $SiteName] < 6)) do={ 92 | $LogMessageFunc ("GetWebPageFunc: arg value $SiteName not a \ 93 | valid string!"); 94 | :return { "duration"="*** test failed ***" } 95 | } 96 | 97 | do { 98 | return [/tool fetch url=("https://$SiteName") mode=https \ 99 | http-method=get as-value keep-result=no]; 100 | } on-error { 101 | $LogMessageFunc ("GetWebPageFunc: unable to retrieve site: \ 102 | $SiteName !"); 103 | :return { "duration"="*** test failed ***" } 104 | } 105 | } 106 | 107 | ########## 108 | # Main 109 | ########## 110 | 111 | # define list of websites to test 112 | :local WebSites { "badsite1234.com"; "www.google.com"; "twitter.com"}; 113 | 114 | # step through each website and perform various tests 115 | :foreach SiteName in=$WebSites do={ 116 | 117 | # try a DNS resolution of this site 118 | :local IpAddress [$DnsResolveFunc $SiteName]; 119 | 120 | # try pinging the IP address of this site 121 | :local PingResult [$PingIpAddressFunc $IpAddress]; 122 | 123 | # try getting the web page of this site 124 | :local UrlFetch [$GetWebPageFunc $SiteName]; 125 | 126 | # print out a summary report for this site 127 | :put "=========================================="; 128 | :put ("Site: $SiteName"); 129 | :put ("IP Address = $IpAddress"); 130 | :put ("Ping success = $PingResult/3"); 131 | :put ("Page d/load duration: " . $UrlFetch->"duration"); 132 | :put "==========================================="; 133 | } 134 | 135 | # cleanup global namespace 136 | :set LogMessageFunc; 137 | :set DnsResolveFunc; 138 | :set PingIpAddressFunc; 139 | :set GetWebPageFunc; 140 | :set DEBUG; 141 | :set DebugFunc; 142 | :set Filename; 143 | -------------------------------------------------------------------------------- /scripts/v6/ch10-09-simple-pause.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch10-09-simple-pause.rsc 2 | 3 | # A simple script that includes a 2 second pause 4 | 5 | :put "Hello we're going to pause now..."; 6 | :delay 2; 7 | :put "Pause complete. We're all done now!"; 8 | -------------------------------------------------------------------------------- /scripts/v6/ch10-10-add-remove-vlans.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch10-10-add-remove-vlans.rsc 2 | 3 | # a script to add and remove 50 VLANs to/fromon-error={ 4 | # a Mikrotik router interface 5 | 6 | :for VlanId from 200 to 249 do={ 7 | 8 | # find LAN interface ID 9 | :local LanInterface "ether2"; 10 | :local LanInterfaceId [/interface find default-name=$LanInterface]; 11 | 12 | # add VLAN to LAN interface 13 | :local VlanName "VLAN$VlanId"; 14 | /interface vlan add name="$VlanName" vlan-id=$VlanId \ 15 | interface=$LanInterfaceId; 16 | } 17 | 18 | :for VlanId from 200 to 249 do={ 19 | 20 | # find LAN interface ID 21 | :local LanInterface "ether2"; 22 | :local LanInterfaceId [/interface find default-name=$LanInterface]; 23 | 24 | # add VLAN to LAN interface 25 | :local VlanName "VLAN$VlanId"; 26 | /interface vlan remove "$VlanName"; 27 | } 28 | -------------------------------------------------------------------------------- /scripts/v6/ch10-11-add-remove-vlans.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch10-11-add-remove-vlans.rsc 2 | 3 | # a script to add and remove 50 VLANs to/from 4 | # a Mikrotik router interface 5 | 6 | # find LAN interface ID 7 | :local LanInterface "ether2"; 8 | :local LanInterfaceId [/interface find default-name=$LanInterface]; 9 | 10 | :for VlanId from 200 to 249 do={ 11 | 12 | # add VLAN to LAN interface 13 | :local VlanName "VLAN$VlanId"; 14 | /interface vlan add name="$VlanName" vlan-id=$VlanId \ 15 | interface=$LanInterfaceId; 16 | } 17 | 18 | :for VlanId from 200 to 249 do={ 19 | 20 | # add VLAN to LAN interface 21 | :local VlanName "VLAN$VlanId"; 22 | /interface vlan remove "$VlanName"; 23 | } 24 | -------------------------------------------------------------------------------- /scripts/v6/ch10-12-add-remove-vlans.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch10-12-add-remove-vlans.rsc 2 | 3 | # a script to add and remove 50 VLANs to/from 4 | # a Mikrotik router interface 5 | 6 | # find LAN interface ID 7 | :local LanInterface "ether2"; 8 | :local LanInterfaceId [/interface find default-name=$LanInterface]; 9 | 10 | :local AddLoopTime [:time { 11 | :for VlanId from 200 to 249 do={ 12 | 13 | # add VLAN to LAN interface 14 | :local VlanName "VLAN$VlanId"; 15 | /interface vlan add name="$VlanName" vlan-id=$VlanId \ 16 | interface=$LanInterfaceId; 17 | } 18 | }]; 19 | 20 | :put "Add loop time: $AddLoopTime"; 21 | 22 | :local RemoveLoopTime [:time { 23 | :for VlanId from 200 to 249 do={ 24 | 25 | # add VLAN to LAN interface 26 | :local VlanName "VLAN$VlanId"; 27 | /interface vlan remove "$VlanName"; 28 | } 29 | }]; 30 | 31 | :put "Remove loop time: $RemoveLoopTime"; 32 | -------------------------------------------------------------------------------- /scripts/v6/ch2-01-hello-world.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch2-01-hello-world.rsc 2 | 3 | # Hello World Script 4 | 5 | :local Message "Hello World!"; 6 | :log info $Message; 7 | -------------------------------------------------------------------------------- /scripts/v6/ch4-01-bad-ip-data-type.rsc: -------------------------------------------------------------------------------- 1 | # ch4-01-bad-ip-data-type.rsc 2 | 3 | # Assign an IP address to a variable 4 | :local InterfaceIp "192.168.99.2"; 5 | 6 | # Print out the variable contents 7 | :put "The interface IP address in \$InterfaceIp is: $InterfaceIp"; 8 | 9 | # It looks like an IP address - let's check to make sure 10 | :put ("The variable data type of \$InterfaceIp is: ". [:typeof $InterfaceIp]); 11 | 12 | # Hmmmm...looks like we need to fix it 13 | :local InterfaceIp [:toip $InterfaceIp]; 14 | 15 | # Let's print the fixed variable 16 | :put "The interface IP address in \$InterfaceIp is now: $InterfaceIp"; 17 | 18 | # Let's check its data type 19 | :put ("The variable data type of \$InterfaceIp is now: ". [:typeof $InterfaceIp]); -------------------------------------------------------------------------------- /scripts/v6/ch5-01-no-semi-colons.rsc: -------------------------------------------------------------------------------- 1 | # ch5-01-no-semi-colons.rsc 2 | 3 | :local MULTIPLIER 10 4 | 5 | :for Number from=1 to=10 do={ 6 | :local Result ($Number * $MULTIPLIER) 7 | :put ("This is an unusually long line. Here is the result $Number \ 8 | times $MULTIPLIER is: $Result") 9 | } 10 | -------------------------------------------------------------------------------- /scripts/v6/ch5-02-semi-colons.rsc: -------------------------------------------------------------------------------- 1 | # ch5-02-semi-colons.rsc 2 | 3 | :local MULTIPLIER 10; 4 | 5 | :for Number from=1 to=10 do={ 6 | :local Result ($Number * $MULTIPLIER); 7 | :put ("This is an unusually long line. Here is the result $Number \ 8 | times $MULTIPLIER is: $Result"); 9 | } -------------------------------------------------------------------------------- /scripts/v6/ch5-03-long-line.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch5-03-long-line.rsc 2 | 3 | # Here is a long line 4 | :put [/interface ethernet find where name~"ether" running true rx-fcs-error=0]; 5 | 6 | # Here is same line across multiple lines 7 | :put [/interface ethernet find where \ 8 | name~"ether" \ 9 | running true \ 10 | rx-fcs-error=0]; 11 | -------------------------------------------------------------------------------- /scripts/v6/ch5-04-no-indentation.rsc: -------------------------------------------------------------------------------- 1 | # ch5-04-no-indentation.rsc 2 | 3 | # Create an if-else statement with no additional indentation 4 | :local DayOfWeek "Monday"; 5 | 6 | if ($DayOfWeek = "Monday") do={:put "Boo...it's Monday." 7 | } else={:put "Yay! It's not Monday!"} -------------------------------------------------------------------------------- /scripts/v6/ch5-05-indentation.rsc: -------------------------------------------------------------------------------- 1 | # ch5-05-indentation.rsc 2 | 3 | # Create an if-else statement with indentation 4 | :local DayOfWeek "Monday"; 5 | 6 | if ($DayOfWeek = "Monday") do={ 7 | :put "Boo...it's Monday."; 8 | } else={ 9 | :put "Yay! It's not Monday!"; 10 | } -------------------------------------------------------------------------------- /scripts/v6/ch6-01-variable-value-test.rsc: -------------------------------------------------------------------------------- 1 | # ch6-01-variable-value-test.rsc 2 | 3 | # Declare a variable with no value 4 | :local BridgeName; 5 | 6 | # Test if the variable has a value 7 | :if ([:typeof $BridgeName] = "nothing") do={ 8 | :put "Test 1: this variable has no value!"; 9 | } else= { 10 | :put ("Test 1: the variable value is: $BridgeName"); 11 | } 12 | 13 | # Set a value for the variable 14 | :set BridgeName "Bridge1"; 15 | 16 | # Test if the variable has a value 17 | :if ([:typeof $BridgeName] = "nothing") do={ 18 | :put "Test 2: this variable has no value!"; 19 | } else= { 20 | :put ("Test 2: the variable value is: $BridgeName"); 21 | } -------------------------------------------------------------------------------- /scripts/v6/ch6-02-undeclared-variable.rsc: -------------------------------------------------------------------------------- 1 | # ch6-02-undeclared-variable.rsc 2 | 3 | # Declare a variable but assign no value 4 | :local RouteDistance; 5 | 6 | # Let's test the data type of the variable 7 | :if ([:typeof $RouteDistance] = "nothing") do={ 8 | :put "Test 1: this variable has no value!"; 9 | } 10 | 11 | # Let's test the data type of a non-existent variable 12 | :if ([:typeof $RouteDist] = "nothing") do={ 13 | :put "Test 2: this variable has no value!"; 14 | } 15 | -------------------------------------------------------------------------------- /scripts/v6/ch6-03-global-scope.rsc: -------------------------------------------------------------------------------- 1 | # ---- global scope start ---- 2 | # filename: ch6-03-global-scope.rsc 3 | 4 | # Let's create a variable in the global scope 5 | :local GlobalScopeVar "I'm in the global scope!"; 6 | 7 | # Let's print it out 8 | :put ("Global scope variable contents = $GlobalScopeVar"); 9 | 10 | # ---- global scope end ---- -------------------------------------------------------------------------------- /scripts/v6/ch6-04-local-scope.rsc: -------------------------------------------------------------------------------- 1 | # ---- global scope start ---- 2 | # filename: ch6-04-local-scope.rsc 3 | 4 | # Let's create a variable in the global scope 5 | :local GlobalScopeVar "I'm in the global scope!"; 6 | 7 | { 8 | # ---- start of a local scope ---- 9 | 10 | # Let's create a variable in this scope 11 | :local LocalScopeVar "I'm in the local scope!"; 12 | 13 | # Let's print out the variable in this scope 14 | :put ("Local scope variable contents = $LocalScopeVar"); 15 | 16 | # ---- end of local scope ---- 17 | } 18 | 19 | # Let's print it out the global scope variable 20 | :put ("Global scope variable contents = $GlobalScopeVar"); 21 | 22 | # Let's print out the local scope variable 23 | # (hint: this won't work) 24 | :put ("Local scope variable contents = $LocalScopeVar"); 25 | 26 | # ---- global scope end ---- -------------------------------------------------------------------------------- /scripts/v6/ch6-05-local-scope.rsc: -------------------------------------------------------------------------------- 1 | # ---- global scope start ---- 2 | # filename: ch6-05-local-scope.rsc 3 | 4 | # Let's create a variable in the global scope 5 | :local GlobalScopeVar "I'm in the global scope!"; 6 | 7 | { 8 | # ---- start of a local scope ---- 9 | 10 | # Let's create a variable in this scope 11 | :local LocalScopeVar "I'm in the local scope!"; 12 | 13 | # Let's print out the variable in this scope 14 | :put ("Local scope variable contents = $LocalScopeVar"); 15 | 16 | # Let's see if we can access the global scope variable 17 | :put ("Global scope variable (in local scope) = $GlobalScopeVar"); 18 | 19 | # ---- end of local scope ---- 20 | } 21 | 22 | # Let's print out the global scope variable 23 | :put ("Global scope variable (in global scope) = $GlobalScopeVar"); 24 | 25 | # ---- global scope end ---- -------------------------------------------------------------------------------- /scripts/v6/ch6-06-local-scope.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch6-06-local-scope.rsc 2 | 3 | # ---- start of a local scope ---- 4 | { 5 | :local apple "green"; 6 | :local banana "yellow"; 7 | :put ("(1) The apple is: $apple"); 8 | :put ("(1) The banana is: $banana"); 9 | 10 | # ---- start of child local scope ---- 11 | { 12 | :local apple "red"; 13 | :put ("(2) The apple is: $apple"); 14 | :put ("(2) The banana is: $banana"); 15 | } 16 | # ---- end of child local scope ---- 17 | 18 | :put ("(3) The apple is: $apple"); 19 | :put ("(3) The banana is: $banana"); 20 | 21 | } 22 | # ---- end of local scope ---- 23 | 24 | :put ("(4) The apple is: $apple"); 25 | :put ("(4) The banana is: $banana"); 26 | 27 | # ---- start of new local scope ---- 28 | { 29 | :local apple "yellow"; 30 | :put ("(5) The apple is: $apple"); 31 | :put ("(5) The banana is: $banana"); 32 | } 33 | # ---- end of new local scope ---- -------------------------------------------------------------------------------- /scripts/v6/ch6-07-variable-types.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch6-07-variable-types.rsc 2 | 3 | # Create a local variable 4 | :local Apple "green"; 5 | 6 | # Print its value 7 | :put ("Local variable contents: $Apple"); 8 | 9 | # Create a global variable 10 | :global Banana "green"; 11 | 12 | # Print its value 13 | :put ("Global variable contents: $Banana"); -------------------------------------------------------------------------------- /scripts/v6/ch6-08-local-vars.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch6-08-local-vars.rsc 2 | 3 | # Create a local variable 4 | :local SmallNumber; 5 | 6 | # Print its value 7 | :put ("Variable contents: $SmallNumber"); 8 | 9 | # Assign some data to the variable 10 | :set SmallNumber 2; 11 | 12 | # Print its value again 13 | :put ("Variable contents: $SmallNumber"); 14 | 15 | # Let's change the variable value 16 | :set SmallNumber 3; 17 | 18 | # Print its value again 19 | :put ("Variable contents: $SmallNumber"); -------------------------------------------------------------------------------- /scripts/v6/ch6-09-local-vars2.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch6-09-local-vars2.rsc 2 | 3 | # Create a local variable that is an array of words 4 | :local Words { "Hello, "; "how "; "are "; "you ?"}; 5 | 6 | # Create a local variable to store concatenated words in a string 7 | :local WordString; 8 | 9 | # Step through each word and add to the "WordString" variable 10 | :foreach Word in=$Words do={ 11 | :put "Word from array: $Word"; 12 | :set WordString ($WordString . $Word); 13 | } 14 | 15 | # Print out the result 16 | :put "\n"; 17 | :put "New string we've built:"; 18 | :put $WordString; 19 | :put "\n"; 20 | :put ("Original array: " . [:tostr $Words]); 21 | -------------------------------------------------------------------------------- /scripts/v6/ch6-10-global-vars.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch6-10-global-vars.rsc 2 | 3 | # Note: this script assumes global vars $Day, 4 | # $Month and $Year have been set via the CLI 5 | # 6 | # Let's get a dump of our current global variables: 7 | :environment print; 8 | 9 | # Let's check we can access each variable: 10 | :put "The day today is $Day"; 11 | :put "The month today is $Month"; 12 | :put "The year today is $Year"; 13 | 14 | # Uh-oh...we had an issue, no values were printed! 15 | :put "\nThat didn't work!\n"; 16 | 17 | # To access global variables declared outside our script 18 | # we need to declare them again within our script, but do 19 | # not assign a value when declaring them: 20 | :global Day; 21 | :global Month; 22 | :global Year 23 | 24 | # Let's try printing them again: 25 | :put "The day today is $Day"; 26 | :put "The month today is $Month"; 27 | :put "The year today is $Year"; 28 | 29 | # Let's declare a new global variable to 30 | # access outside of this script: 31 | :global TimeOfDay "morning"; 32 | :global Breakfast "muesli"; 33 | 34 | # Lets get a dump of our current global variables: 35 | :put "\nCurrent global variables:\n"; 36 | :environment print; 37 | -------------------------------------------------------------------------------- /scripts/v6/ch6-11-global-vars2.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch6-11-global-vars2.rsc 2 | 3 | # Lets get a dump of our current global variables: 4 | :environment print; 5 | 6 | # Let's declare a new global variable 7 | :global Beverage "coffee"; 8 | 9 | # Let's declare global vars that already exist so that 10 | # we may access them 11 | :global Fruit; 12 | :global TellTheTruth; 13 | 14 | # Let's print modify the vars if we no not 15 | # wish to tell the truth 16 | if ($TellTheTruth = false) do={ 17 | :set Fruit "bananas"; 18 | :set Beverage "beer"; 19 | } 20 | 21 | # Let's see which are my favourite fruit and 22 | # beverage 23 | :put "My favourite fruit is: $Fruit"; 24 | :put "My favourite beverage is: $Beverage"; 25 | 26 | if ($TellTheTruth = false) do={ 27 | :put "(pssst...this is actually a lie)"; 28 | } 29 | 30 | # Lets get a dump of our current global variables: 31 | :put "\nCurrent global variables:\n"; 32 | :environment print; 33 | -------------------------------------------------------------------------------- /scripts/v6/ch6-12-global-vars3.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch6-12-global-vars3.rsc 2 | 3 | # In this script, we expect to have several interface names 4 | # in a global variable called "WanInterfaces". The variable 5 | # should be an array for the script to work correctly 6 | 7 | # Declare the "WanInterfaces" global variable to access 8 | # its data (assuming it exists) 9 | :global WanInterfaces; 10 | 11 | # Does it have a value? If not, exit with an error 12 | if ( [:typeof $WanInterfaces] = "nothing") do={ 13 | :error "The WanInterfaces global variable is not set. Exiting" 14 | } 15 | 16 | # Is the variable an array data type? 17 | if ( [:typeof $WanInterfaces] != "array") do={ 18 | :error "The WanInterfaces global variable is not an array data \ 19 | type. Exiting." 20 | } 21 | 22 | # Let's step through the interfaces in the array 23 | # and print out their operation status 24 | :foreach WanInterface in=$WanInterfaces do={ 25 | :local InterfaceId [/interface ethernet find name=$WanInterface]; 26 | 27 | :local UpDown "down"; 28 | if ([/interface ethernet get $InterfaceId]->"running") do={ 29 | :set UpDown "up" 30 | } 31 | 32 | :put "Interface $WanInterface is currently $UpDown"; 33 | } 34 | 35 | # Let's assume no-one else will need the "WanInterfaces" 36 | # variable. Let's remove it from global variables 37 | :set WanInterfaces; 38 | 39 | -------------------------------------------------------------------------------- /scripts/v6/ch7-01-basic-if.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch7-01-basic-if.rsc 2 | 3 | # Print a greeting 4 | :put "Hello, I hope you're well."; 5 | 6 | # Check if the time is after 6pm (get time in 21:46:04 format) 7 | :local CurrentTime [/system clock get time]; 8 | :put "The current time is : $CurrentTime"; 9 | 10 | # Say good evening if time is after 18:00 11 | :if ($CurrentTime > 18:00) do={ 12 | :put "Good evening!"; 13 | } 14 | 15 | # Say goodbye 16 | :put "Thanks for visiting, bye!"; -------------------------------------------------------------------------------- /scripts/v6/ch7-02-basic-if.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch7-02-basic-if.rsc 2 | 3 | # Create a variable for the WAN interface name 4 | :local WanInterface "ether1-WAN"; 5 | 6 | # Create a variable for the number of pings we'd like to send 7 | :local PingCount 10; 8 | 9 | # Create a variable for the destination on the Internet to ping 10 | :local DestinationAddress 8.8.8.8; 11 | 12 | # Let's try a ping to the Internet across the WAN interface 13 | :local WanPingCount [/ping $DestinationAddress interface=$WanInterface \ 14 | count=$PingCount]; 15 | 16 | # Let's log the result of our Internet connection test 17 | if ( $WanPingCount = $PingCount) do={ 18 | :log info "The Internet is up."; 19 | } 20 | 21 | if ( $WanPingCount = 0) do={ 22 | :log error "The Internet is down."; 23 | 24 | } 25 | 26 | if ( ($WanPingCount < $PingCount) and ($WanPingCount > 0) ) do={ 27 | :log warning "The Internet connection may be degraded. (Ping \ 28 | result: $WanPingCount/$PingCount)"; 29 | } 30 | -------------------------------------------------------------------------------- /scripts/v6/ch7-03-if-else.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch7-03-if-else.rsc 2 | 3 | # Print a greeting 4 | :put "Hello, I hope you're well."; 5 | 6 | # Check if the time is after 6pm (get time in 21:46:04 format) 7 | :local CurrentTime [/system clock get time]; 8 | :put "The current time is : $CurrentTime"; 9 | 10 | # Say good morning if time is before 12:00 11 | :if ($CurrentTime > 12:00) do={ 12 | :put "Good day!"; 13 | } else={ 14 | :put "Good morning!"; 15 | } 16 | 17 | # Say goodbye 18 | :put "Thanks for visiting, bye!"; -------------------------------------------------------------------------------- /scripts/v6/ch7-04-if-else-vars.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch7-04-if-else-vars.rsc 2 | 3 | # Get the current time 4 | :local CurrentTime [/system clock get time]; 5 | :put "The current time is : $CurrentTime"; 6 | 7 | # Check if it's after noon 8 | :if ($CurrentTime > 12:00) do={ 9 | :local TimeOfDay "Afternoon/Evening"; 10 | } else={ 11 | # otherwise, it must be morning (00:00 to 11:59) 12 | :local TimeOfDay "Morning"; 13 | } 14 | 15 | # Print out the time of day 16 | :put "At the moment, it's : $TimeOfDay"; -------------------------------------------------------------------------------- /scripts/v6/ch7-05-if-else-vars2.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch7-05-if-else-vars2.rsc 2 | 3 | # Get the current time 4 | :local CurrentTime [/system clock get time]; 5 | :put "The current time is : $CurrentTime"; 6 | 7 | # declare the time of day variable 8 | :local TimeOfDay; 9 | 10 | # Check if it's after noon 11 | :if ($CurrentTime > 12:00) do={ 12 | :set TimeOfDay "Afternoon/Evening"; 13 | } else={ 14 | # otherwise, it must be morning (00:00 to 11:59) 15 | :set TimeOfDay "Morning"; 16 | } 17 | 18 | # Print out the time of day 19 | :put "At the moment, it's : $TimeOfDay"; -------------------------------------------------------------------------------- /scripts/v6/ch7-06-if-multiple-conditions.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch7-06-multiple-conditions.rsc 2 | 3 | # Get the current time 4 | :local CurrentTime [/system clock get time]; 5 | :put "The current time is : $CurrentTime"; 6 | 7 | # declare the time of day variable 8 | :local TimeOfDay; 9 | 10 | # Check if it's very early 11 | :if (($CurrentTime >= 00:00) and ($CurrentTime < 06:00)) do={ 12 | :put "It's very early in the morning...shouldn't you be in bed?"; 13 | } 14 | 15 | # Check if its morning 16 | :if (($CurrentTime >= 06:00) and ($CurrentTime < 12:00)) do={ 17 | :put "Good morning!"; 18 | } 19 | 20 | # Check if its afternoon 21 | :if (($CurrentTime >= 12:00) and ($CurrentTime < 17:00)) do={ 22 | :put "Good afternoon!"; 23 | } 24 | 25 | # check if its evening 26 | :if (($CurrentTime >= 17:00) and ($CurrentTime < 00:00)) do={ 27 | :put "Good evening!"; 28 | } 29 | -------------------------------------------------------------------------------- /scripts/v6/ch7-07-nested-if-statements.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch7-07-nested-if-statements.rsc 2 | 3 | # Get the current time 4 | :local CurrentTime [/system clock get time]; 5 | :put "The current time is : $CurrentTime"; 6 | 7 | # declare the time of day variable 8 | :local TimeOfDay; 9 | 10 | # Check if it's before noon 11 | :if ($CurrentTime < 12:00) do={ 12 | 13 | # it's before noon, let's see what time of the morning 14 | # it is using a nested if-else statement 15 | if ($CurrentTime < 06:00) do={ 16 | :set TimeOfDay "It's very early in the morning...shouldn't \ 17 | you be in bed?"; 18 | } else={ 19 | # it must be between 06:01 and 11:59 to reach here 20 | :set TimeOfDay "Good morning!"; 21 | } 22 | # end of nested if-else statement 23 | 24 | } else={ 25 | 26 | # it must be after noon, let's see if it's evening or 27 | # afternoon using a nested if-else statement 28 | if ($CurrentTime < 18:00) do={ 29 | :set TimeOfDay "Good afternoon!"; 30 | } else={ 31 | # it must be between 18:00 and 23:59 to reach here 32 | :set TimeOfDay "Good evening!"; 33 | } 34 | # end of nested if-else statement 35 | 36 | } 37 | 38 | :put $TimeOfDay; -------------------------------------------------------------------------------- /scripts/v6/ch7-08-if-else-binary.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch7-08-if-else-binary.rsc 2 | 3 | # define WAN interface name 4 | :local WanInterfaceName "ether1-WAN"; 5 | 6 | # find the interface ID 7 | :local InterfaceId [/interface ethernet find name=$WanInterfaceName]; 8 | 9 | :local UpDown; 10 | 11 | if ([/interface ethernet get $InterfaceId]->"running") do={ 12 | :set UpDown "up"; 13 | } else={ 14 | :set UpDown "down"; 15 | } 16 | 17 | :put "Interface $WanInterfaceName is currently $UpDown"; -------------------------------------------------------------------------------- /scripts/v6/ch7-09-if-binary-simplified.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch7-09-if-binary-simplified.rsc 2 | 3 | # define WAN interface name 4 | :local WanInterfaceName "ether1-WAN"; 5 | 6 | # find the interface index 7 | :local InterfaceId [/interface ethernet find name=$WanInterfaceName]; 8 | 9 | :local UpDown "down"; 10 | if ([/interface ethernet get $InterfaceId]->"running") do={ 11 | :set UpDown "up" 12 | } 13 | 14 | :put "Interface $WanInterface is currently $UpDown"; -------------------------------------------------------------------------------- /scripts/v6/ch8-01-for-basic.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch8-01-for-basic.rsc 2 | 3 | # Let's print out a series of numbers and part of 4 | # the 12 times table 5 | :for LoopCount from=1 to=5 do={ 6 | 7 | :put "Current loop counter is: $LoopCount"; 8 | :put ("12 x $LoopCount is: " . (12 * $LoopCount)); 9 | } 10 | 11 | # Print out the final loop count (fails!) 12 | :put ("Final loop count is: " . $LoopCount); 13 | -------------------------------------------------------------------------------- /scripts/v6/ch8-02-for-check-web.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch8-02-for-check-web.rsc 2 | 3 | # define an array of web sites 4 | :local WebSites {"mikrotik.com"; "google.com"; "twitter.com"}; 5 | 6 | # use a simple for loop to check if each site is reachable 7 | :for SiteIndex from=0 to=2 do={ 8 | 9 | :local Site ($WebSites->$SiteIndex); 10 | 11 | :put "Pinging web site: $Site"; 12 | 13 | :local PingResult [/ping $Site count=3 ]; 14 | :if ($PingResult > 0) do { 15 | :put "\nWeb site $Site reached OK\n"; 16 | } else={ 17 | :put "\nNo response from web site: $Site\n"; 18 | } 19 | } -------------------------------------------------------------------------------- /scripts/v6/ch8-03-for-create-vlan.rsc: -------------------------------------------------------------------------------- 1 | # ch8-03-for-create-vlan.rsc 2 | 3 | # define the interface where we'd like to add a VLAN 4 | # !! Set this to a valid interface name on your Mikrotik !! 5 | :local InterfaceName "ether5"; 6 | 7 | # create a for loop with a step of 10 8 | :for VlanId from=100 to=150 step=10 do={ 9 | 10 | :put ("Creating VLAN $VlanId on interface $InterfaceName"); 11 | :local VlanName ("vlan" . $VlanId); 12 | /interface vlan add name=$VlanName vlan-id=$VlanId \ 13 | interface=$InterfaceName; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /scripts/v6/ch8-04-foreach-web.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch8-04-foreach-web.rsc 2 | 3 | # define an array of web sites 4 | :local WebSites {"mikrotik.com"; "google.com"; "twitter.com"}; 5 | 6 | # use a foreach loop to check if each site is reachable 7 | :foreach Site in=$WebSites do={ 8 | 9 | :put "Pinging web site: $Site"; 10 | 11 | :local PingResult [/ping $Site count=3 ]; 12 | 13 | :if ($PingResult > 0) do { 14 | :put ("\nWeb site $Site reached OK\n"); 15 | } else={ 16 | :put ("\nNo response from web site: $Site\n"); 17 | } 18 | } -------------------------------------------------------------------------------- /scripts/v6/ch8-05-foreach-kv.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch8-05-foreach-kv.rsc 2 | 3 | # define an array of interface data 4 | :local InterfaceErrors {"WAN"=514; "LAN"=0; "ether3"=0; "ether4"=0; 5}; 5 | 6 | # use a foreach loop to print out the error value for each interface 7 | :foreach InterfaceName,ErrorCounter in=$InterfaceErrors do={ 8 | :put "$InterfaceName errors: $ErrorCounter"; 9 | } -------------------------------------------------------------------------------- /scripts/v6/ch8-06-while-infinite.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch8-06-while-infinite.rsc 2 | 3 | # Let's create an infinite loop using "while" 4 | 5 | :local LoopCounter 5; 6 | 7 | :while ($LoopCounter <= 10) do={ 8 | 9 | # print out the current loop counter value 10 | :put "Value of loop counter is: $LoopCounter"; 11 | 12 | # decrement the counter 13 | :set LoopCounter ($LoopCounter - 1); 14 | 15 | # add in a pause to prevent cpu thrashing 16 | :delay 1; 17 | } 18 | 19 | # print a message when/if the loop exits 20 | :put "Loop has exited!"; -------------------------------------------------------------------------------- /scripts/v6/ch8-07-while-with-exit.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch8-07-while-with-exit.rsc 2 | 3 | # Let's create a loop using "while" 4 | 5 | :local LoopCounter 5; 6 | 7 | :while ($LoopCounter <= 10) do={ 8 | 9 | # print out the current loop counter value 10 | :put "Value of loop counter is: $LoopCounter"; 11 | 12 | # increment the counter 13 | :set LoopCounter ($LoopCounter + 1); 14 | } 15 | 16 | # print a message when/if the loop exits 17 | :put "Loop has exited!"; -------------------------------------------------------------------------------- /scripts/v6/ch8-08-while-timer.rsc: -------------------------------------------------------------------------------- 1 | # ch8-08-while-timer.rsc 2 | 3 | # script to report page load time of google.com 4 | 5 | # get the current time 6 | :local CurrentTime [/system clock get time]; 7 | 8 | # calculate the time in 1 minute 9 | :local EndTime ($CurrentTime + 00:01:00); 10 | 11 | # define a target web site 12 | :local WebSite "www.google.com"; 13 | 14 | # run a while loop until one minute interval has expired 15 | :while ( [/system clock get time] < $EndTime ) do={ 16 | 17 | :put "Getting web page from $WebSite"; 18 | 19 | # fetch a page from web site 20 | :local FetchResult; 21 | :local TimeTaken [:time { 22 | :set FetchResult [/tool fetch url=("https://$WebSite") \ 23 | mode=https http-method=get as-value keep-result=no]; 24 | }]; 25 | 26 | if ($FetchResult->"status" = "finished") do={ 27 | # print out how long page retrieval took (if successful) 28 | :put "Web page fetch time: $TimeTaken secs"; 29 | } else={ 30 | # print failure message if fetch failed 31 | :put "Web page fetch failed"; 32 | } 33 | 34 | # pause for 5 seconds 35 | :delay 5; 36 | } 37 | :put "One minute period has ended!" 38 | -------------------------------------------------------------------------------- /scripts/v6/ch8-09-while-alt-form.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch8-09-while-alt-form.rsc 2 | 3 | # Let's create a loop using "while" 4 | 5 | :local LoopCounter 5; 6 | 7 | :do { 8 | 9 | # print out the current loop counter value 10 | :put "Value of loop counter is: $LoopCounter"; 11 | 12 | # increment the counter 13 | :set LoopCounter ($LoopCounter + 1); 14 | 15 | } while ($LoopCounter <= 4) 16 | 17 | # print a message when/if the loop exits 18 | :put "Loop has exited!"; -------------------------------------------------------------------------------- /scripts/v6/ch9-01-mac-fixer.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch9-01-mac-fixer.rsc 2 | 3 | # Let's create function to remove colon characters 4 | # from a MAC address passed as an argument 5 | 6 | # --- start of function --- 7 | :global MacColonRemoveFunc do={ 8 | :local TidyMac ""; 9 | for CharNumber from=0 to=([:len $1]-1) do={ 10 | :local TmpValue [:pick $1 $CharNumber]; 11 | :if ($TmpValue !=":") do={ :set TidyMac "$TidyMac$TmpValue" } 12 | } 13 | :return $TidyMac; 14 | } 15 | # --- end of function --- 16 | 17 | # Now, let's call the function with some values 18 | :local MacAddress "00:08:EF:44:98:18" 19 | :put ("$MacAddress becomes: " . [$MacColonRemoveFunc $MacAddress]); 20 | 21 | :set MacAddress "DC:2C:6E:DF:D5:F6" 22 | :put ("$MacAddress becomes: " . [$MacColonRemoveFunc $MacAddress]); 23 | 24 | # Cleanup global namespace 25 | :set MacColonRemoveFunc; 26 | -------------------------------------------------------------------------------- /scripts/v6/ch9-02-mutiple-args-simple.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch9-02-multiple-args-simple.rsc 2 | 3 | # Let's create function to receive multiple args 4 | 5 | # --- start of function --- 6 | :global PrintInterfaceAttrsFunc do={ 7 | 8 | :local InterfaceName $1; 9 | :local InterfaceSpeed $2; 10 | :local InterfaceIp $3; 11 | 12 | # check args are correct data types 13 | if ([:typeof $InterfaceName] != "str") do={ 14 | :error "Interface name argument not a string!"; 15 | } 16 | 17 | if ([:typeof $InterfaceSpeed] != "str") do={ 18 | :error "InterfaceSpeed argument not a string!"; 19 | } 20 | 21 | if ([:typeof $InterfaceIp] != "str") do={ 22 | :error "Interface IP argument not a string!"; 23 | } 24 | 25 | # data type checks passed, print the interface data 26 | :put "$InterfaceName: IP address = $InterfaceIp, speed = \ 27 | $InterfaceSpeed"; 28 | 29 | } 30 | # --- end of function --- 31 | 32 | # Let's call the function with some sample values ($1, $2, $3) 33 | $PrintInterfaceAttrsFunc "WAN1" "100Mbps" "192.168.99.1/24"; 34 | 35 | # Let's call the function with some other values ($1, $2, $3) 36 | $PrintInterfaceAttrsFunc "ether2-LAN" "1000Mbps" "172.16.1.254/24"; 37 | 38 | # Cleanup global namespace 39 | :set PrintInterfaceAttrsFunc; 40 | 41 | -------------------------------------------------------------------------------- /scripts/v6/ch9-03-mutiple-args-array.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch9-03-multiple-args-array.rsc 2 | 3 | # Let's create function to receive a single array arg 4 | 5 | # --- start of function --- 6 | :global PrintInterfaceAttrsFunc do={ 7 | 8 | # verify arg is correct type 9 | if ([:typeof $1] != "array") do={ 10 | :error "Function argument is not an array!"; 11 | } 12 | 13 | # extract values from array passed as arg 14 | :local Args $1; 15 | :local InterfaceName ($Args->"ifname"); 16 | :local InterfaceSpeed ($Args->"ifspeed"); 17 | :local InterfaceIp ($Args->"ifip"); 18 | 19 | # check args are correct data types 20 | if ([:typeof $InterfaceName] != "str") do={ 21 | :error "InterfaceName argument not a string!"; 22 | } 23 | 24 | if ([:typeof $InterfaceSpeed] != "str") do={ 25 | :error "InterfaceSpeed argument not a string!"; 26 | } 27 | 28 | if ([:typeof $InterfaceIp] != "str") do={ 29 | :error "InterfaceIp argument not a string!"; 30 | } 31 | 32 | # data type checks passed, print the interface data 33 | :put "$InterfaceName: IP address = $InterfaceIp, speed = \ 34 | $InterfaceSpeed"; 35 | } 36 | # --- end of function --- 37 | 38 | # Let's call the function with some sample values in an array 39 | :local Args { ifname="WAN1"; ifspeed="100Mbps"; \ 40 | ifip="192.168.99.1/24" }; 41 | $PrintInterfaceAttrsFunc $Args; 42 | 43 | # Let's call the function with some other values in an array 44 | :set Args { ifname="ether2-LAN"; ifspeed="1000Mbps"; \ 45 | ifip="172.16.1.254/24" }; 46 | $PrintInterfaceAttrsFunc $Args; 47 | 48 | # Cleanup global namespace 49 | :set PrintInterfaceAttrsFunc; 50 | -------------------------------------------------------------------------------- /scripts/v6/ch9-04-create-global-func.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch9-04-create-global-func.rsc 2 | 3 | # function to remove spaces from a string 4 | # 5 | # e.g. :local NoSpaceVar [$RemoveSpaceFunc "string with spaces"] 6 | # 7 | :global RemoveSpaceFunc do={ 8 | :local NewName "" 9 | for CharNumber from=0 to=([:len $1]-1) do={ 10 | :local Tmp [:pick $1 $CharNumber] 11 | :if ($Tmp !=" ") do={ :set NewName "$NewName$Tmp" } 12 | } 13 | :return $NewName 14 | } 15 | # --- end of function --- -------------------------------------------------------------------------------- /scripts/v6/ch9-05-use-global-func.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch9-05-use-global-func.rsc 2 | 3 | # declare the name of the global function we wish to use 4 | # to make it available in our script 5 | :global RemoveSpaceFunc; 6 | 7 | # creates a string that contains spaces 8 | :local StringWithSpaces "txBroadcast = 201"; 9 | 10 | # print original string 11 | :put ("String with spaces: $StringWithSpaces"); 12 | 13 | # print string that is modified by function 14 | :local StringNoSpaces [$RemoveSpaceFunc $StringWithSpaces]; 15 | :put ("String with no spaces: $StringNoSpaces"); 16 | -------------------------------------------------------------------------------- /scripts/v6/ch9-06-str-funcs-mod.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch9-06-str-funcs-mod.rsc 2 | 3 | # function to remove spaces from a string 4 | # 5 | # e.g. :local NoSpaceVar [$RemoveSpaceFunc "string with spaces"] 6 | # 7 | :global RemoveSpaceFunc do={ 8 | :local NewName "" 9 | for CharNumber from=0 to=([:len $1]-1) do={ 10 | :local Tmp [:pick $1 $CharNumber] 11 | :if ($Tmp !=" ") do={ :set NewName "$NewName$Tmp" } 12 | } 13 | :return $NewName 14 | } 15 | # --- end of function --- 16 | 17 | # function to remove last char from a string 18 | # 19 | # e.g. :local ChoppedVar [$ChopStrFunc "string with extra char,"] 20 | # 21 | :global ChopStrFunc do={ 22 | :return [ :pick $1 0 ( [ :len $1 ] -1 ) ]; 23 | } 24 | # --- end of function --- -------------------------------------------------------------------------------- /scripts/v6/ch9-07-use-str-module.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch9-07-use-str-module.rsc 2 | 3 | # import the functions we need and declare the functions 4 | # names we wish to use 5 | /import "ch9-06-str-funcs-mod.rsc" 6 | :global RemoveSpaceFunc; 7 | :global ChopStrFunc; 8 | 9 | # check our function names are valid 10 | if ([:typeof $RemoveSpaceFunc] != "array") do={ 11 | :error "RemoveSpaceFunc is wrong data type or does not exist."; 12 | } 13 | 14 | if ([:typeof $ChopStrFunc] != "array") do={ 15 | :error "ChopStrFunc is wrong data type or does not exist."; 16 | } 17 | 18 | # create a string to use with the functions 19 | :local StringToModify "txBroadcast = 201,"; 20 | 21 | # print original string 22 | :put ("Orignal string: $StringToModify"); 23 | 24 | # use both functions to modify the string 25 | :local ModifiedString [$RemoveSpaceFunc $StringToModify]; 26 | :set ModifiedString [$ChopStrFunc $ModifiedString]; 27 | :put ("Modified string: $ModifiedString"); 28 | 29 | # tidy up the global namespace (optional) 30 | :set RemoveSpaceFunc; 31 | :set ChopStrFunc; 32 | -------------------------------------------------------------------------------- /scripts/v7/ch1-01-board-type.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch1-01-board-type.rsc 2 | 3 | # A simple script to print your Mikrotik board type 4 | 5 | :local BoardType [/system/resource get board]; 6 | :put "Your Mikrotik board type is : $BoardType"; 7 | -------------------------------------------------------------------------------- /scripts/v7/ch1-02-get-board-arch.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch1-02-get-board-arch.rsc 2 | 3 | # A simple script to print your Mikrotik board architecture 4 | 5 | :local ArchitectureName [/system/resource get architecture-name]; 6 | :put "Your Mikrotik board architecture is : $ArchitectureName"; -------------------------------------------------------------------------------- /scripts/v7/ch10-01-bad-script.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch10-01-bad-script.rsc 2 | 3 | :local w {"mikrotik.com"; "www.google.com"; "twitter.com"}; 4 | 5 | :foreach s in=$w do={ 6 | :local i [:resolve $s]; 7 | :local p [/ping $i count=3]; 8 | :local u [/tool fetch url=("https://$s") mode=https http-method=get \ 9 | as-value keep-result=no]; 10 | 11 | :put "=========================================="; 12 | :put ("Site: $s"); 13 | :put ("IP Address = $i"); 14 | :put ("Ping success = $p/3"); 15 | :put ("Page d/load duration: " . $u->"duration"); 16 | :put "==========================================="; 17 | } 18 | -------------------------------------------------------------------------------- /scripts/v7/ch10-02-bad-script.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch10-02-bad-script.rsc 2 | # 3 | # A simple script to perform a series of tests on a 4 | # list of web sites. 5 | 6 | # define list of websites to test 7 | :local w {"mikrotik.com"; "www.google.com"; "twitter.com"}; 8 | 9 | # step through each website and perform various tests 10 | :foreach s in=$w do={ 11 | 12 | # try a DNS resolution of this site 13 | :local i [:resolve $s]; 14 | 15 | # try pinging the IP address of this site 16 | :local p [/ping $i count=3]; 17 | 18 | # try fetching the web page of this site 19 | :local u [/tool fetch url=("https://$s") mode=https http-method=get \ 20 | as-value keep-result=no]; 21 | 22 | # print out a summary report for this site 23 | :put "=========================================="; 24 | :put ("Site: $s"); 25 | :put ("IP Address = $i"); 26 | :put ("Ping success = $p/3"); 27 | :put ("Page d/load duration: " . $u->"duration"); 28 | :put "==========================================="; 29 | } 30 | -------------------------------------------------------------------------------- /scripts/v7/ch10-03-bad-script.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch10-03-bad-script.rsc 2 | # 3 | # A simple script to perform a series of tests on a 4 | # list of web sites. 5 | 6 | # define list of websites to test 7 | :local WebSites {"mikrotik.com"; "www.google.com"; "twitter.com"}; 8 | 9 | # step through each website and perform various tests 10 | :foreach SiteName in=$WebSites do={ 11 | 12 | # try a DNS resolution of this site 13 | :local IpAddress [:resolve $SiteName]; 14 | 15 | # try pinging the IP address of this site 16 | :local PingResult [/ping $IpAddress count=3]; 17 | 18 | # try getting the web page of this site 19 | :local UrlFetch [/tool fetch url=("https://$SiteName") mode=https \ 20 | http-method=get as-value keep-result=no]; 21 | 22 | # print out a summary report for this site 23 | :put "=========================================="; 24 | :put ("Site: $SiteName"); 25 | :put ("IP Address = $IpAddress"); 26 | :put ("Ping success = $PingResult/3"); 27 | :put ("Page d/load duration: " . $UrlFetch->"duration"); 28 | :put "==========================================="; 29 | } 30 | -------------------------------------------------------------------------------- /scripts/v7/ch10-04-bad-script.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch10-04-bad-script.rsc 2 | # 3 | # A simple script to perform a series of tests on a 4 | # list of web sites. 5 | 6 | :global Filename "ch10-04-bad-script.rsc"; 7 | 8 | # function to log error message 9 | :global LogMessageFunc do={ 10 | :global Filename; 11 | :local ErrorMessage ("$Filename: $1"); 12 | 13 | :log error $ErrorMessage; 14 | :error $ErrorMessage; 15 | } 16 | 17 | # function to DNS resolve a site name to IP 18 | :global DnsResolveFunc do={ 19 | :local WebSiteName $1; 20 | :global LogMessageFunc; 21 | 22 | # check arg type str of correct length passed 23 | if (([:typeof $WebSiteName]!="str") or \ 24 | ([:len $WebSiteName] < 6)) do={ 25 | $LogMessageFunc ("DnsResolveFunc: arg value $WebSiteName not \ 26 | a valid string!"); 27 | } 28 | 29 | return [:resolve $WebSiteName]; 30 | } 31 | 32 | # function to ping an IP address 3 times 33 | :global PingIpAddressFunc do={ 34 | :local IpAddress $1; 35 | :global LogMessageFunc; 36 | 37 | # check arg type ip is passed 38 | if ([:typeof $IpAddress] != "ip") do={ 39 | $LogMessageFunc ("PingIpAddressFunc: arg value $IpAddress not \ 40 | an IP address!"); 41 | } 42 | 43 | return [/ping $IpAddress count=3]; 44 | } 45 | 46 | # function to return the result of fetching a web page 47 | :global GetWebPageFunc do={ 48 | :local SiteName $1; 49 | :global LogMessageFunc; 50 | 51 | # check arg type str of correct length passed 52 | if (([:typeof $SiteName] != "str") or \ 53 | ([:len $SiteName] < 6)) do={ 54 | $LogMessageFunc ("GetWebPageFunc: arg value $SiteName not a \ 55 | valid string!"); 56 | } 57 | 58 | return [/tool fetch url=("https://$SiteName") mode=https \ 59 | http-method=get as-value keep-result=no]; 60 | } 61 | 62 | ########## 63 | # Main 64 | ########## 65 | 66 | # define list of websites to test 67 | :local WebSites { "mikrotik.com"; "www.google.com"; "twitter.com"}; 68 | 69 | # step through each website and perform various tests 70 | :foreach SiteName in=$WebSites do={ 71 | 72 | # try a DNS resolution of this site 73 | :local IpAddress [$DnsResolveFunc $SiteName]; 74 | 75 | # try pinging the IP address of this site 76 | :local PingResult [$PingIpAddressFunc $IpAddress]; 77 | 78 | # try getting the web page of this site 79 | :local UrlFetch [$GetWebPageFunc $SiteName]; 80 | 81 | # print out a summary report for this site 82 | :put "=========================================="; 83 | :put ("Site: $SiteName"); 84 | :put ("IP Address = $IpAddress"); 85 | :put ("Ping success = $PingResult/3"); 86 | :put ("Page d/load duration: " . $UrlFetch->"duration"); 87 | :put "==========================================="; 88 | } 89 | 90 | # cleanup global namespace 91 | :set LogMessageFunc; 92 | :set DnsResolveFunc; 93 | :set PingIpAddressFunc; 94 | :set GetWebPageFunc; 95 | :set Filename; 96 | -------------------------------------------------------------------------------- /scripts/v7/ch10-05-error_check.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch10-05-error-check.rsc 2 | :local WebSites { "badname1234.com"; "google.com"}; 3 | 4 | :foreach SiteName in=$WebSites do={ 5 | :local SiteIpAddress [:resolve $SiteName]; 6 | :put "Site IP for $SiteName is $SiteIpAddress"; 7 | } 8 | -------------------------------------------------------------------------------- /scripts/v7/ch10-06-error_check.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch10-06-error-check.rsc 2 | :local WebSites { "badname1234.com"; "google.com"}; 3 | :foreach SiteName in=$WebSites do={ 4 | :do { 5 | :local SiteIpAddress [:resolve $SiteName]; 6 | :put "Site IP for $SiteName is $SiteIpAddress"; 7 | } on-error={ 8 | :put "Name lookup failed for $SiteName"; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /scripts/v7/ch10-07-bad-script.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch10-07-bad-script.rsc 2 | # 3 | # A simple script to perform a series of tests on a 4 | # list of web sites. 5 | 6 | :global Filename "ch10-07-bad-script.rsc"; 7 | 8 | # function to log error messages 9 | :global LogMessageFunc do={ 10 | :global Filename; 11 | :local ErrorMessage "$Filename: $1"; 12 | 13 | :log error $ErrorMessage; 14 | :put $ErrorMessage; # print to CLI 15 | } 16 | 17 | # function to DNS resolve a site name to IP 18 | :global DnsResolveFunc do={ 19 | :local WebSiteName $1; 20 | :global LogMessageFunc; 21 | 22 | # check arg type str of correct length passed 23 | :if (([:typeof $WebSiteName] != "str") or \ 24 | ([:len $WebSiteName] < 6)) do={ 25 | $LogMessageFunc ("DnsResolveFunc: arg value $WebSiteName not \ 26 | a valid string!"); 27 | 28 | :return "*** test failed ***"; 29 | } 30 | 31 | # try a name lookup 32 | :do { 33 | return [:resolve $WebSiteName]; 34 | } on-error={ 35 | $LogMessageFunc ("DnsResolveFunc: name resolution failed for \ 36 | site: $WebSiteName!"); 37 | :return "*** test failed ***"; 38 | } 39 | } 40 | 41 | # function to ping an IP address 3 times 42 | :global PingIpAddressFunc do={ 43 | :local IpAddress $1; 44 | :global LogMessageFunc; 45 | 46 | # check arg type ip is passed 47 | :if ([:typeof $IpAddress] != "ip") do={ 48 | $LogMessageFunc ("PingIpAddressFunc: arg value $IpAddress not \ 49 | an IP address!"); 50 | :return "*** test failed ***"; 51 | } 52 | 53 | # try a ping 54 | :do { 55 | return [/ping $IpAddress count=3]; 56 | } on-error={ 57 | $LogMessageFunc ("PingIpAddressFunc: ping test failed: \ 58 | $IpAddress !"); 59 | :return "*** test failed ***"; 60 | } 61 | } 62 | 63 | # function to return the result of fetching a web page 64 | :global GetWebPageFunc do={ 65 | :local SiteName $1; 66 | :global LogMessageFunc; 67 | 68 | # check arg type str of correct length passed 69 | :if (([:typeof $SiteName] != "str") or \ 70 | ([:len $SiteName] < 6)) do={ 71 | $LogMessageFunc ("GetWebPageFunc: arg value $SiteName not a \ 72 | valid string!"); 73 | :return "*** test failed ***"; 74 | } 75 | 76 | # try to get web page 77 | :do { 78 | :return [/tool fetch url=("https://$SiteName") mode=https \ 79 | http-method=get as-value keep-result=no]; 80 | } on-error={ 81 | $LogMessageFunc ("GetWebPageFunc: unable to retrieve site: \ 82 | $SiteName !"); 83 | :return { "duration"="*** test failed ***" } 84 | } 85 | } 86 | 87 | ########## 88 | # Main 89 | ########## 90 | 91 | # define list of websites to test 92 | :local WebSites { "badsite1234.com"; "www.google.com"; "twitter.com"}; 93 | 94 | # step through each website and perform various tests 95 | :foreach SiteName in=$WebSites do={ 96 | 97 | # try a DNS resolution of this site 98 | :local IpAddress [$DnsResolveFunc $SiteName]; 99 | 100 | # try pinging the IP address of this site 101 | :local PingResult [$PingIpAddressFunc $IpAddress]; 102 | 103 | # try getting the web page of this site 104 | :local UrlFetch [$GetWebPageFunc $SiteName]; 105 | 106 | # print out a summary report for this site 107 | :put "=========================================="; 108 | :put ("Site: $SiteName"); 109 | :put ("IP Address = $IpAddress"); 110 | :put ("Ping success = $PingResult/3"); 111 | :put ("Page d/load duration: " . $UrlFetch->"duration"); 112 | :put "==========================================="; 113 | } 114 | 115 | # cleanup global namespace 116 | :set LogMessageFunc; 117 | :set DnsResolveFunc; 118 | :set PingIpAddressFunc; 119 | :set GetWebPageFunc; 120 | :set Filename; 121 | -------------------------------------------------------------------------------- /scripts/v7/ch10-08-bad-script.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch10-08-bad-script.rsc 2 | # 3 | # A simple script to perform a series of tests on a 4 | # list of web sites. 5 | 6 | :global Filename "ch10-08-bad-script.rsc"; 7 | 8 | # set DEBUG to "true" for script debugging output, 9 | # "false" for normal operation 10 | :global DEBUG false; 11 | 12 | # debug function 13 | :global DebugFunc do={ 14 | :global DEBUG; 15 | :if ($DEBUG) do={ :put "**Debug: $1"; } 16 | } 17 | 18 | # function to log error messages 19 | :global LogMessageFunc do={ 20 | :global Filename; 21 | :local ErrorMessage "$Filename: $1"; 22 | 23 | :log error $ErrorMessage; 24 | :put $ErrorMessage; # print to CLI 25 | } 26 | 27 | # function to DNS resolve a site name to IP 28 | :global DnsResolveFunc do={ 29 | :local WebSiteName $1; 30 | :global LogMessageFunc; 31 | :global DebugFunc; 32 | 33 | $DebugFunc "Entering DnsResolveFunc"; 34 | $DebugFunc ("Arg passed to func: $WebSiteName"); 35 | 36 | # check arg type str of correct length passed 37 | $DebugFunc "Checking arg data type is correct"; 38 | 39 | :if (([:typeof $WebSiteName] != "str") or \ 40 | ([:len $WebSiteName] < 6)) do={ 41 | :local ErrorMsg "DnsResolveFunc: arg value $WebSiteName \ 42 | not a valid string!"; 43 | $LogMessageFunc $ErrorMsg; 44 | $DebugFunc $ErrorMsg; 45 | :return "*** test failed ***"; 46 | } else={ 47 | $DebugFunc "Data type looks good"; 48 | } 49 | 50 | :do { 51 | $DebugFunc "Looking up IP of site name..."; 52 | :local SiteIpAddr [:resolve $WebSiteName]; 53 | $DebugFunc $SiteIpAddr; 54 | :return $SiteIpAddr; 55 | } on-error={ 56 | $DebugFunc "DNS lookup failed!"; 57 | $LogMessageFunc ("DnsResolveFunc: name resolution failed for \ 58 | site: $WebSiteName!"); 59 | :return "*** test failed ***"; 60 | } 61 | } 62 | 63 | # function to ping an IP address 3 times 64 | :global PingIpAddressFunc do={ 65 | :local IpAddress $1; 66 | :global LogMessageFunc; 67 | 68 | # check arg type ip is passed 69 | :if ([:typeof $IpAddress] != "ip") do={ 70 | $LogMessageFunc ("PingIpAddressFunc: arg value $IpAddress not \ 71 | an IP address!"); 72 | :return "*** test failed ***"; 73 | } 74 | 75 | :do { 76 | return [/ping $IpAddress count=3]; 77 | } on-error { 78 | $LogMessageFunc ("PingIpAddressFunc: ping test to IP address \ 79 | failed: $IpAddress !"); 80 | :return "*** test failed ***"; 81 | } 82 | } 83 | 84 | # function to return the result of fetching a web page 85 | :global GetWebPageFunc do={ 86 | :local SiteName $1; 87 | :global LogMessageFunc; 88 | 89 | # check arg type str of correct length passed 90 | if (([:typeof $SiteName] != "str") or \ 91 | ([:len $SiteName] < 6)) do={ 92 | $LogMessageFunc ("GetWebPageFunc: arg value $SiteName not a \ 93 | valid string!"); 94 | :return { "duration"="*** test failed ***" } 95 | } 96 | 97 | do { 98 | return [/tool fetch url=("https://$SiteName") mode=https \ 99 | http-method=get as-value keep-result=no]; 100 | } on-error { 101 | $LogMessageFunc ("GetWebPageFunc: unable to retrieve site: \ 102 | $SiteName !"); 103 | :return { "duration"="*** test failed ***" } 104 | } 105 | } 106 | 107 | ########## 108 | # Main 109 | ########## 110 | 111 | # define list of websites to test 112 | :local WebSites { "badsite1234.com"; "www.google.com"; "twitter.com"}; 113 | 114 | # step through each website and perform various tests 115 | :foreach SiteName in=$WebSites do={ 116 | 117 | # try a DNS resolution of this site 118 | :local IpAddress [$DnsResolveFunc $SiteName]; 119 | 120 | # try pinging the IP address of this site 121 | :local PingResult [$PingIpAddressFunc $IpAddress]; 122 | 123 | # try getting the web page of this site 124 | :local UrlFetch [$GetWebPageFunc $SiteName]; 125 | 126 | # print out a summary report for this site 127 | :put "=========================================="; 128 | :put ("Site: $SiteName"); 129 | :put ("IP Address = $IpAddress"); 130 | :put ("Ping success = $PingResult/3"); 131 | :put ("Page d/load duration: " . $UrlFetch->"duration"); 132 | :put "==========================================="; 133 | } 134 | 135 | # cleanup global namespace 136 | :set LogMessageFunc; 137 | :set DnsResolveFunc; 138 | :set PingIpAddressFunc; 139 | :set GetWebPageFunc; 140 | :set DEBUG; 141 | :set DebugFunc; 142 | :set Filename; 143 | -------------------------------------------------------------------------------- /scripts/v7/ch10-09-simple-pause.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch10-09-simple-pause.rsc 2 | 3 | # A simple script that includes a 2 second pause 4 | 5 | :put "Hello we're going to pause now..."; 6 | :delay 2; 7 | :put "Pause complete. We're all done now!"; 8 | -------------------------------------------------------------------------------- /scripts/v7/ch10-10-add-remove-vlans.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch10-10-add-remove-vlans.rsc 2 | 3 | # a script to add and remove 50 VLANs to/from 4 | # a Mikrotik router interface 5 | 6 | :for VlanId from 200 to 249 do={ 7 | 8 | # find LAN interface ID 9 | :local LanInterface "ether2"; 10 | :local LanInterfaceId [/interface find default-name=$LanInterface]; 11 | 12 | # add VLAN to LAN interface 13 | :local VlanName "VLAN$VlanId"; 14 | /interface/vlan add name="$VlanName" vlan-id=$VlanId \ 15 | interface=$LanInterfaceId; 16 | } 17 | 18 | :for VlanId from 200 to 249 do={ 19 | 20 | # find LAN interface ID 21 | :local LanInterface "ether2"; 22 | :local LanInterfaceId [/interface find default-name=$LanInterface]; 23 | 24 | # add VLAN to LAN interface 25 | :local VlanName "VLAN$VlanId"; 26 | /interface/vlan remove "$VlanName"; 27 | } 28 | -------------------------------------------------------------------------------- /scripts/v7/ch10-11-add-remove-vlans.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch10-11-add-remove-vlans.rsc 2 | 3 | # a script to add and remove 50 VLANs to/from 4 | # a Mikrotik router interface 5 | 6 | # find LAN interface ID 7 | :local LanInterface "ether2"; 8 | :local LanInterfaceId [/interface find default-name=$LanInterface]; 9 | 10 | :for VlanId from 200 to 249 do={ 11 | 12 | # add VLAN to LAN interface 13 | :local VlanName "VLAN$VlanId"; 14 | /interface vlan add name="$VlanName" vlan-id=$VlanId \ 15 | interface=$LanInterfaceId; 16 | } 17 | 18 | :for VlanId from 200 to 249 do={ 19 | 20 | # add VLAN to LAN interface 21 | :local VlanName "VLAN$VlanId"; 22 | /interface vlan remove "$VlanName"; 23 | } 24 | -------------------------------------------------------------------------------- /scripts/v7/ch10-12-add-remove-vlans.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch10-12-add-remove-vlans.rsc 2 | 3 | # a script to add and remove 50 VLANs to/from 4 | # a Mikrotik router interface 5 | 6 | # find LAN interface ID 7 | :local LanInterface "ether2"; 8 | :local LanInterfaceId [/interface find default-name=$LanInterface]; 9 | 10 | :local AddLoopTime [:time { 11 | :for VlanId from 200 to 249 do={ 12 | 13 | # add VLAN to LAN interface 14 | :local VlanName "VLAN$VlanId"; 15 | /interface vlan add name="$VlanName" vlan-id=$VlanId \ 16 | interface=$LanInterfaceId; 17 | } 18 | }]; 19 | 20 | :put "Add loop time: $AddLoopTime"; 21 | 22 | :local RemoveLoopTime [:time { 23 | :for VlanId from 200 to 249 do={ 24 | 25 | # add VLAN to LAN interface 26 | :local VlanName "VLAN$VlanId"; 27 | /interface vlan remove "$VlanName"; 28 | } 29 | }]; 30 | 31 | :put "Remove loop time: $RemoveLoopTime"; 32 | -------------------------------------------------------------------------------- /scripts/v7/ch2-01-hello-world.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch2-01-hello-world.rsc 2 | 3 | # Hello World Script 4 | 5 | :local Message "Hello World!"; 6 | :log info $Message; 7 | -------------------------------------------------------------------------------- /scripts/v7/ch4-01-bad-ip-data-type.rsc: -------------------------------------------------------------------------------- 1 | # ch4-01-bad-ip-data-type.rsc 2 | 3 | # Assign an IP address to a variable 4 | :local InterfaceIp "192.168.99.2"; 5 | 6 | # Print out the variable contents 7 | :put "The interface IP address in \$InterfaceIp is: $InterfaceIp"; 8 | 9 | # It looks like an IP address - let's check to make sure 10 | :put ("The variable data type of \$InterfaceIp is: ". [:typeof $InterfaceIp]); 11 | 12 | # Hmmmm...looks like we need to fix it 13 | :local InterfaceIp [:toip $InterfaceIp]; 14 | 15 | # Let's print the fixed variable 16 | :put "The interface IP address in \$InterfaceIp is now: $InterfaceIp"; 17 | 18 | # Let's check its data type 19 | :put ("The variable data type of \$InterfaceIp is now: ". [:typeof $InterfaceIp]); -------------------------------------------------------------------------------- /scripts/v7/ch5-01-no-semi-colons.rsc: -------------------------------------------------------------------------------- 1 | # ch5-01-no-semi-colons.rsc 2 | 3 | :local MULTIPLIER 10 4 | 5 | :for Number from=1 to=10 do={ 6 | :local Result ($Number * $MULTIPLIER) 7 | :put ("This is an unusually long line. Here is the result \ 8 | $Number times $MULTIPLIER is: $Result") 9 | } 10 | -------------------------------------------------------------------------------- /scripts/v7/ch5-02-semi-colons.rsc: -------------------------------------------------------------------------------- 1 | # ch5-02-semi-colons.rsc 2 | 3 | :local MULTIPLIER 10; 4 | 5 | :for Number from=1 to=10 do={ 6 | :local Result ($Number * $MULTIPLIER); 7 | :put ("This is an unusually long line. Here is the result $Number \ 8 | times $MULTIPLIER is: $Result"); 9 | } 10 | -------------------------------------------------------------------------------- /scripts/v7/ch5-03-long-line.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch5-03-long-line.rsc 2 | 3 | # Here is a long line 4 | :put [/interface/ethernet find where name~"ether" running true rx-fcs-error=0]; 5 | 6 | # Here is same line across multiple lines 7 | :put [/interface/ethernet find where \ 8 | name~"ether" \ 9 | running true \ 10 | rx-fcs-error=0]; 11 | -------------------------------------------------------------------------------- /scripts/v7/ch5-04-no-indentation.rsc: -------------------------------------------------------------------------------- 1 | # ch5-04-no-indentation.rsc 2 | 3 | # Create an if-else statement with no additional indentation 4 | :local DayOfWeek "Monday"; 5 | 6 | if ($DayOfWeek = "Monday") do={:put "Boo...it's Monday." 7 | } else={:put "Yay! It's not Monday!"} -------------------------------------------------------------------------------- /scripts/v7/ch5-05-indentation.rsc: -------------------------------------------------------------------------------- 1 | # ch5-05-indentation.rsc 2 | 3 | # Create an if-else statement with no additional indentation 4 | :local DayOfWeek "Monday"; 5 | 6 | if ($DayOfWeek = "Monday") do={ 7 | :put "Boo...it's Monday."; 8 | } else={ 9 | :put "Yay! It's not Monday!"; 10 | } -------------------------------------------------------------------------------- /scripts/v7/ch6-01-variable-value-test.rsc: -------------------------------------------------------------------------------- 1 | # ch6-01-variable-value-test.rsc 2 | 3 | # Declare a variable with no value 4 | :local BridgeName; 5 | 6 | # Test if the variable has a value 7 | :if ([:typeof $BridgeName] = "nothing") do={ 8 | :put "Test 1: this variable has no value!"; 9 | } else= { 10 | :put ("Test 1: the variable value is: $BridgeName"); 11 | } 12 | 13 | # Set a value for the variable 14 | :set BridgeName "Bridge1"; 15 | 16 | # Test if the variable has a value 17 | :if ([:typeof $BridgeName] = "nothing") do={ 18 | :put "Test 2: this variable has no value!"; 19 | } else= { 20 | :put ("Test 2: the variable value is: $BridgeName"); 21 | } -------------------------------------------------------------------------------- /scripts/v7/ch6-02-undeclared-variable.rsc: -------------------------------------------------------------------------------- 1 | # ch6-02-undeclared-variable.rsc 2 | 3 | # Declare a variable but assign no value 4 | :local RouteDistance; 5 | 6 | # Let's test the data type of the variable 7 | :if ([:typeof $RouteDistance] = "nothing") do={ 8 | :put "Test 1: this variable has no value!"; 9 | } 10 | 11 | # Let's test the data type of a non-existent variable 12 | :if ([:typeof $RouteDist] = "nothing") do={ 13 | :put "Test 2: this variable has no value!"; 14 | } 15 | -------------------------------------------------------------------------------- /scripts/v7/ch6-03-global-scope.rsc: -------------------------------------------------------------------------------- 1 | # ---- global scope start ---- 2 | # filename: ch6-03-global-scope.rsc 3 | 4 | # Let's create a variable in the global scope 5 | :local GlobalScopeVar "I'm in the global scope!"; 6 | 7 | # Let's print it out 8 | :put ("Global scope variable contents = $GlobalScopeVar"); 9 | 10 | # ---- global scope end ---- -------------------------------------------------------------------------------- /scripts/v7/ch6-04-local-scope.rsc: -------------------------------------------------------------------------------- 1 | # ---- global scope start ---- 2 | # filename: ch6-04-local-scope.rsc 3 | 4 | # Let's create a variable in the global scope 5 | :local GlobalScopeVar "I'm in the global scope!"; 6 | 7 | { 8 | # ---- start of a local scope ---- 9 | 10 | # Let's create a variable in this scope 11 | :local LocalScopeVar "I'm in the local scope!"; 12 | 13 | # Let's print out the variable in this scope 14 | :put ("Local scope variable contents = $LocalScopeVar"); 15 | 16 | # ---- end of local scope ---- 17 | } 18 | 19 | # Let's print it out the global scope variable 20 | :put ("Global scope variable contents = $GlobalScopeVar"); 21 | 22 | # Let's print out the local scope variable 23 | # (hint: this won't work) 24 | :put ("Local scope variable contents = $LocalScopeVar"); 25 | 26 | # ---- global scope end ---- -------------------------------------------------------------------------------- /scripts/v7/ch6-05-local-scope.rsc: -------------------------------------------------------------------------------- 1 | # ---- global scope start ---- 2 | # filename: ch6-05-local-scope.rsc 3 | 4 | # Let's create a variable in the global scope 5 | :local GlobalScopeVar "I'm in the global scope!"; 6 | 7 | { 8 | # ---- start of a local scope ---- 9 | 10 | # Let's create a variable in this scope 11 | :local LocalScopeVar "I'm in the local scope!"; 12 | 13 | # Let's print out the variable in this scope 14 | :put ("Local scope variable contents = $LocalScopeVar"); 15 | 16 | # Let's see if we can access the global scope variable 17 | :put ("Global scope variable (in local scope) = $GlobalScopeVar"); 18 | 19 | # ---- end of local scope ---- 20 | } 21 | 22 | # Let's print out the global scope variable 23 | :put ("Global scope variable (in global scope) = $GlobalScopeVar"); 24 | 25 | # ---- global scope end ---- -------------------------------------------------------------------------------- /scripts/v7/ch6-06-local-scope.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch6-06-local-scope.rsc 2 | 3 | # ---- start of a local scope ---- 4 | { 5 | :local apple "green"; 6 | :local banana "yellow"; 7 | :put ("(1) The apple is: $apple"); 8 | :put ("(1) The banana is: $banana"); 9 | 10 | # ---- start of child local scope ---- 11 | { 12 | :local apple "red"; 13 | :put ("(2) The apple is: $apple"); 14 | :put ("(2) The banana is: $banana"); 15 | } 16 | # ---- end of child local scope ---- 17 | 18 | :put ("(3) The apple is: $apple"); 19 | :put ("(3) The banana is: $banana"); 20 | 21 | } 22 | # ---- end of local scope ---- 23 | 24 | :put ("(4) The apple is: $apple"); 25 | :put ("(4) The banana is: $banana"); 26 | 27 | # ---- start of new local scope ---- 28 | { 29 | :local apple "yellow"; 30 | :put ("(5) The apple is: $apple"); 31 | :put ("(5) The banana is: $banana"); 32 | } 33 | # ---- end of new local scope ---- -------------------------------------------------------------------------------- /scripts/v7/ch6-07-variable-types.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch6-07-variable-types.rsc 2 | 3 | # Create a local variable 4 | :local Apple "green"; 5 | 6 | # Print its value 7 | :put ("Local variable contents: $Apple"); 8 | 9 | # Create a global variable 10 | :global Banana "green"; 11 | 12 | # Print its value 13 | :put ("Global variable contents: $Banana"); -------------------------------------------------------------------------------- /scripts/v7/ch6-08-local-vars.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch6-08-local-vars.rsc 2 | 3 | # Create a local variable 4 | :local SmallNumber; 5 | 6 | # Print its value 7 | :put ("Variable contents: $SmallNumber"); 8 | 9 | # Assign some data to the variable 10 | :set SmallNumber 2; 11 | 12 | # Print its value again 13 | :put ("Variable contents: $SmallNumber"); 14 | 15 | # Let's change the variable value 16 | :set SmallNumber 3; 17 | 18 | # Print its value again 19 | :put ("Variable contents: $SmallNumber"); -------------------------------------------------------------------------------- /scripts/v7/ch6-09-local-vars2.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch6-09-local-vars2.rsc 2 | 3 | # Create a local variable that is an array of words 4 | :local Words { "Hello, "; "how "; "are "; "you ?"}; 5 | 6 | # Create a local variable to store concatenated words in a string 7 | :local WordString; 8 | 9 | # Step through each word and add to the "WordString" variable 10 | :foreach Word in=$Words do={ 11 | :put "Word from array: $Word"; 12 | :set WordString ($WordString . $Word); 13 | } 14 | 15 | # Print out the result 16 | :put "\n"; 17 | :put "New string we've built:"; 18 | :put $WordString; 19 | :put "\n"; 20 | :put ("Original array: " . [:tostr $Words]); 21 | -------------------------------------------------------------------------------- /scripts/v7/ch6-10-global-vars.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch6-10-global-vars.rsc 2 | 3 | # Note: this script assumes global vars $Day, 4 | # $Month and $Year have been set via the CLI 5 | # 6 | # Let's get a dump of our current global variables: 7 | :environment print; 8 | 9 | # Let's check we can access each variable: 10 | :put "The day today is $Day"; 11 | :put "The month today is $Month"; 12 | :put "The year today is $Year"; 13 | 14 | # Uh-oh...we had an issue, no values were printed! 15 | :put "\nThat didn't work!\n"; 16 | 17 | # To access global variables declared outside our script 18 | # we need to declare them again within our script, but do 19 | # not assign a value when declaring them: 20 | :global Day; 21 | :global Month; 22 | :global Year 23 | 24 | # Let's try printing them again: 25 | :put "The day today is $Day"; 26 | :put "The month today is $Month"; 27 | :put "The year today is $Year"; 28 | 29 | # Let's declare a new global variable to 30 | # access outside of this script: 31 | :global TimeOfDay "morning"; 32 | :global Breakfast "muesli"; 33 | 34 | # Lets get a dump of our current global variables: 35 | :put "\nCurrent global variables:\n"; 36 | :environment print; 37 | -------------------------------------------------------------------------------- /scripts/v7/ch6-11-global-vars2.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch6-11-global-vars2.rsc 2 | 3 | # Lets get a dump of our current global variables: 4 | :environment print; 5 | 6 | # Let's declare a new global variable 7 | :global Beverage "coffee"; 8 | 9 | # Let's declare global vars that already exist so that 10 | # we may access them 11 | :global Fruit; 12 | :global TellTheTruth; 13 | 14 | # Let's print modify the vars if we no not 15 | # wish to tell the truth 16 | if ($TellTheTruth = false) do={ 17 | :set Fruit "bananas"; 18 | :set Beverage "beer"; 19 | } 20 | 21 | # Let's see which are my favourite fruit and 22 | # beverage 23 | :put "My favourite fruit is: $Fruit"; 24 | :put "My favourite beverage is: $Beverage"; 25 | 26 | if ($TellTheTruth = false) do={ 27 | :put "(pssst...this is actually a lie)"; 28 | } 29 | 30 | # Lets get a dump of our current global variables: 31 | :put "\nCurrent global variables:\n"; 32 | :environment print; 33 | -------------------------------------------------------------------------------- /scripts/v7/ch6-12-global-vars3.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch6-12-global-vars3.rsc 2 | 3 | # In this script, we expect to have several interface names 4 | # in a global variable called "WanInterfaces". The variable 5 | # should be an array for the script to work correctly 6 | 7 | # Declare the "WanInterfaces" global variable to access 8 | # its data (assuming it exists) 9 | :global WanInterfaces; 10 | 11 | # Does it have a value? If not, exit with an error 12 | if ( [:typeof $WanInterfaces] = "nothing") do={ 13 | :error "The WanInterfaces global variable is not set. Exiting" 14 | } 15 | 16 | # Is the variable an array data type? 17 | if ( [:typeof $WanInterfaces] != "array") do={ 18 | :error "The WanInterfaces global variable is not an array data \ 19 | type. Exiting." 20 | } 21 | 22 | # Let's step through the interfaces in the array 23 | # and print out their operation status 24 | :foreach WanInterface in=$WanInterfaces do={ 25 | :local InterfaceId [/interface/ethernet find name=$WanInterface]; 26 | 27 | :local UpDown "down"; 28 | if ([/interface/ethernet get $InterfaceId]->"running") do={ 29 | :set UpDown "up" 30 | } 31 | 32 | :put "Interface $WanInterface is currently $UpDown"; 33 | } 34 | 35 | # Let's assume no-one else will need the "WanInterfaces" 36 | # variable. Let's remove it from global variables 37 | :set WanInterfaces; 38 | 39 | -------------------------------------------------------------------------------- /scripts/v7/ch7-01-basic-if.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch7-01-basic-if.rsc 2 | 3 | # Print a greeting 4 | :put "Hello, I hope you're well."; 5 | 6 | # Check if the time is after 6pm (get time in 21:46:04 format) 7 | :local CurrentTime [/system clock get time]; 8 | :put "The current time is : $CurrentTime"; 9 | 10 | # Say good evening if time is after 18:00 11 | :if ($CurrentTime > 18:00) do={ 12 | :put "Good evening!"; 13 | } 14 | 15 | # Say goodbye 16 | :put "Thanks for visiting, bye!"; -------------------------------------------------------------------------------- /scripts/v7/ch7-02-basic-if.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch7-02-basic-if.rsc 2 | 3 | # Create a variable for the WAN interface name 4 | :local WanInterface "ether1-WAN"; 5 | 6 | # Create a variable for the number of pings we'd like to send 7 | :local PingCount 10; 8 | 9 | # Create a variable for the destination on the Internet to ping 10 | :local DestinationAddress 8.8.8.8; 11 | 12 | # Let's try a ping to the Internet across the WAN interface 13 | :local WanPingCount [/ping $DestinationAddress interface=$WanInterface \ 14 | count=$PingCount]; 15 | 16 | # Let's log the result of our Internet connection test 17 | if ( $WanPingCount = $PingCount) do={ 18 | :log info "The Internet is up."; 19 | } 20 | 21 | if ( $WanPingCount = 0) do={ 22 | :log error "The Internet is down."; 23 | 24 | } 25 | 26 | if ( ($WanPingCount < $PingCount) and ($WanPingCount > 0) ) do={ 27 | :log warning "The Internet connection may be degraded. (Ping \ 28 | result: $WanPingCount/$PingCount)"; 29 | } 30 | -------------------------------------------------------------------------------- /scripts/v7/ch7-03-if-else.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch7-03-if-else.rsc 2 | 3 | # Print a greeting 4 | :put "Hello, I hope you're well."; 5 | 6 | # Check if the time is after 6pm (get time in 21:46:04 format) 7 | :local CurrentTime [/system clock get time]; 8 | :put "The current time is : $CurrentTime"; 9 | 10 | # Say good morning if time is before 12:00 11 | :if ($CurrentTime > 12:00) do={ 12 | :put "Good day!"; 13 | } else={ 14 | :put "Good morning!"; 15 | } 16 | 17 | # Say goodbye 18 | :put "Thanks for visiting, bye!"; -------------------------------------------------------------------------------- /scripts/v7/ch7-04-if-else-vars.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch7-04-if-else-vars.rsc 2 | 3 | # Get the current time 4 | :local CurrentTime [/system clock get time]; 5 | :put "The current time is : $CurrentTime"; 6 | 7 | # Check if it's after noon 8 | :if ($CurrentTime > 12:00) do={ 9 | :local TimeOfDay "Afternoon/Evening"; 10 | } else={ 11 | # otherwise, it must be morning (00:00 to 11:59) 12 | :local TimeOfDay "Morning"; 13 | } 14 | 15 | # Print out the time of day 16 | :put "At the moment, it's : $TimeOfDay"; -------------------------------------------------------------------------------- /scripts/v7/ch7-05-if-else-vars2.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch7-05-if-else-vars2.rsc 2 | 3 | # Get the current time 4 | :local CurrentTime [/system clock get time]; 5 | :put "The current time is : $CurrentTime"; 6 | 7 | # declare the time of day variable 8 | :local TimeOfDay; 9 | 10 | # Check if it's after noon 11 | :if ($CurrentTime > 12:00) do={ 12 | :set TimeOfDay "Afternoon/Evening"; 13 | } else={ 14 | # otherwise, it must be morning (00:00 to 11:59) 15 | :set TimeOfDay "Morning"; 16 | } 17 | 18 | # Print out the time of day 19 | :put "At the moment, it's : $TimeOfDay"; -------------------------------------------------------------------------------- /scripts/v7/ch7-06-if-multiple-conditions.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch7-06-multiple-conditions.rsc 2 | 3 | # Get the current time 4 | :local CurrentTime [/system clock get time]; 5 | :put "The current time is : $CurrentTime"; 6 | 7 | # declare the time of day variable 8 | :local TimeOfDay; 9 | 10 | # Check if it's very early 11 | :if (($CurrentTime >= 00:00) and ($CurrentTime < 06:00)) do={ 12 | :put "It's very early in the morning...shouldn't you be in bed?"; 13 | } 14 | 15 | # Check if its morning 16 | :if (($CurrentTime >= 06:00) and ($CurrentTime < 12:00)) do={ 17 | :put "Good morning!"; 18 | } 19 | 20 | # Check if its afternoon 21 | :if (($CurrentTime >= 12:00) and ($CurrentTime < 17:00)) do={ 22 | :put "Good afternoon!"; 23 | } 24 | 25 | # check if its evening 26 | :if (($CurrentTime >= 17:00) and ($CurrentTime < 00:00)) do={ 27 | :put "Good evening!"; 28 | } 29 | -------------------------------------------------------------------------------- /scripts/v7/ch7-07-nested-if-statements.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch7-07-nested-if-statements.rsc 2 | 3 | # Get the current time 4 | :local CurrentTime [/system clock get time]; 5 | :put "The current time is : $CurrentTime"; 6 | 7 | # declare the time of day variable 8 | :local TimeOfDay; 9 | 10 | # Check if it's before noon 11 | :if ($CurrentTime < 12:00) do={ 12 | 13 | # it's before noon, let's see what time of the morning 14 | # it is using a nested if-else statement 15 | if ($CurrentTime < 06:00) do={ 16 | :set TimeOfDay "It's very early in the morning...shouldn't \ 17 | you be in bed?"; 18 | } else={ 19 | # it must be between 06:01 and 11:59 to reach here 20 | :set TimeOfDay "Good morning!"; 21 | } 22 | # end of nested if-else statement 23 | 24 | } else={ 25 | 26 | # it must be after noon, let's see if it's evening or 27 | # afternoon using a nested if-else statement 28 | if ($CurrentTime < 18:00) do={ 29 | :set TimeOfDay "Good afternoon!"; 30 | } else={ 31 | # it must be between 18:00 and 23:59 to reach here 32 | :set TimeOfDay "Good evening!"; 33 | } 34 | # end of nested if-else statement 35 | 36 | } 37 | 38 | :put $TimeOfDay; -------------------------------------------------------------------------------- /scripts/v7/ch7-08-if-else-binary.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch7-08-if-else-binary.rsc 2 | 3 | # define WAN interface name 4 | :local WanInterfaceName "ether1-WAN"; 5 | 6 | # find the interface ID 7 | :local InterfaceId [/interface/ethernet find name=$WanInterfaceName]; 8 | 9 | :local UpDown; 10 | 11 | if ([/interface ethernet get $InterfaceId]->"running") do={ 12 | :set UpDown "up"; 13 | } else={ 14 | :set UpDown "down"; 15 | } 16 | 17 | :put "Interface $WanInterfaceName is currently $UpDown"; -------------------------------------------------------------------------------- /scripts/v7/ch7-09-if-binary-simplified.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch7-09-if-binary-simplified.rsc 2 | 3 | # define WAN interface name 4 | :local WanInterfaceName "ether1-WAN"; 5 | 6 | # find the interface index 7 | :local InterfaceId [/interface/ethernet find name=$WanInterfaceName]; 8 | 9 | :local UpDown "down"; 10 | if ([/interface/ethernet get $InterfaceId]->"running") do={ 11 | :set UpDown "up" 12 | } 13 | 14 | :put "Interface $WanInterface is currently $UpDown"; -------------------------------------------------------------------------------- /scripts/v7/ch8-01-for-basic.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch8-01-for-basic.rsc 2 | 3 | # Let's print out a series of numbers and part of 4 | # the 12 times table 5 | :for LoopCount from=1 to=5 do={ 6 | 7 | :put "Current loop counter is: $LoopCount"; 8 | :put ("12 x $LoopCount is: " . (12 * $LoopCount)); 9 | } 10 | 11 | # Print out the final loop count (fails!) 12 | :put ("Final loop count is: " . $LoopCount); 13 | -------------------------------------------------------------------------------- /scripts/v7/ch8-02-for-check-web.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch8-02-for-check-web.rsc 2 | 3 | # define an array of web sites 4 | :local WebSites {"mikrotik.com"; "google.com"; "twitter.com"}; 5 | 6 | # use a simple for loop to check if each site is reachable 7 | :for SiteIndex from=0 to=2 do={ 8 | 9 | :local Site ($WebSites->$SiteIndex); 10 | 11 | :put "Pinging web site: $Site"; 12 | 13 | :local PingResult [/ping $Site count=3 ]; 14 | :if ($PingResult > 0) do { 15 | :put "\nWeb site $Site reached OK\n"; 16 | } else={ 17 | :put "\nNo response from web site: $Site\n"; 18 | } 19 | } -------------------------------------------------------------------------------- /scripts/v7/ch8-03-for-create-vlan.rsc: -------------------------------------------------------------------------------- 1 | # ch8-03-for-create-vlan.rsc 2 | 3 | # define the interface where we'd like to add a VLAN 4 | # !! Set this to a valid interface name on your Mikrotik !! 5 | :local InterfaceName "ether5"; 6 | 7 | # create a for loop with a step of 10 8 | :for VlanId from=100 to=150 step=10 do={ 9 | 10 | :put ("Creating VLAN $VlanId on interface $InterfaceName"); 11 | :local VlanName ("vlan" . $VlanId); 12 | /interface vlan add name=$VlanName vlan-id=$VlanId \ 13 | interface=$InterfaceName; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /scripts/v7/ch8-04-foreach-web.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch8-04-foreach-web.rsc 2 | 3 | # define an array of web sites 4 | :local WebSites {"mikrotik.com"; "google.com"; "twitter.com"}; 5 | 6 | # use a foreach loop to check if each site is reachable 7 | :foreach Site in=$WebSites do={ 8 | 9 | :put "Pinging web site: $Site"; 10 | 11 | :local PingResult [/ping $Site count=3 ]; 12 | 13 | :if ($PingResult > 0) do { 14 | :put ("\nWeb site $Site reached OK\n"); 15 | } else={ 16 | :put ("\nNo response from web site: $Site\n"); 17 | } 18 | } -------------------------------------------------------------------------------- /scripts/v7/ch8-05-foreach-kv.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch8-05-foreach-kv.rsc 2 | 3 | # define an array of interface data 4 | :local InterfaceErrors {"WAN"=514; "LAN"=0; "ether3"=0; "ether4"=0; 5}; 5 | 6 | # use a foreach loop to print out the error value for each interface 7 | :foreach InterfaceName,ErrorCounter in=$InterfaceErrors do={ 8 | :put "$InterfaceName errors: $ErrorCounter"; 9 | } -------------------------------------------------------------------------------- /scripts/v7/ch8-06-while-infinite.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch8-06-while-infinite.rsc 2 | 3 | # Let's create an infinite loop using "while" 4 | 5 | :local LoopCounter 5; 6 | 7 | :while ($LoopCounter <= 10) do={ 8 | 9 | # print out the current loop counter value 10 | :put "Value of loop counter is: $LoopCounter"; 11 | 12 | # decrement the counter 13 | :set LoopCounter ($LoopCounter - 1); 14 | 15 | # add in a pause to prevent cpu thrashing 16 | :delay 1; 17 | } 18 | 19 | # print a message when/if the loop exits 20 | :put "Loop has exited!"; -------------------------------------------------------------------------------- /scripts/v7/ch8-07-while-with-exit.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch8-07-while-with-exit.rsc 2 | 3 | # Let's create a loop using "while" 4 | 5 | :local LoopCounter 5; 6 | 7 | :while ($LoopCounter <= 10) do={ 8 | 9 | # print out the current loop counter value 10 | :put "Value of loop counter is: $LoopCounter"; 11 | 12 | # increment the counter 13 | :set LoopCounter ($LoopCounter + 1); 14 | } 15 | 16 | # print a message when/if the loop exits 17 | :put "Loop has exited!"; -------------------------------------------------------------------------------- /scripts/v7/ch8-08-while-timer.rsc: -------------------------------------------------------------------------------- 1 | # ch8-08-while-timer.rsc 2 | 3 | # script to report page load time of google.com 4 | 5 | # get the current time 6 | :local CurrentTime [/system clock get time]; 7 | 8 | # calculate the time in 1 minute 9 | :local EndTime ($CurrentTime + 00:01:00); 10 | 11 | # define a target web site 12 | :local WebSite "www.google.com"; 13 | 14 | # run a while loop until one minute interval has expired 15 | :while ( [/system/clock get time] < $EndTime ) do={ 16 | 17 | :put "Getting web page from $WebSite"; 18 | 19 | # fetch a page from web site 20 | :local FetchResult; 21 | :local TimeTaken [:time { 22 | :set FetchResult [/tool fetch url=("https://$WebSite") \ 23 | mode=https http-method=get as-value keep-result=no]; 24 | }]; 25 | 26 | if ($FetchResult->"status" = "finished") do={ 27 | # print out how long page retrieval took (if successful) 28 | :put "Web page fetch time: $TimeTaken secs"; 29 | } else={ 30 | # print failure message if fetch failed 31 | :put "Web page fetch failed"; 32 | } 33 | 34 | # pause for 5 seconds 35 | :delay 5; 36 | } 37 | :put "One minute period has ended!" 38 | 39 | -------------------------------------------------------------------------------- /scripts/v7/ch8-09-while-alt-form.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch8-09-while-alt-form.rsc 2 | 3 | # Let's create a loop using "while" 4 | 5 | :local LoopCounter 5; 6 | 7 | :do { 8 | 9 | # print out the current loop counter value 10 | :put "Value of loop counter is: $LoopCounter"; 11 | 12 | # increment the counter 13 | :set LoopCounter ($LoopCounter + 1); 14 | 15 | } while ($LoopCounter <= 4) 16 | 17 | # print a message when/if the loop exits 18 | :put "Loop has exited!"; -------------------------------------------------------------------------------- /scripts/v7/ch9-01-mac-fixer.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch9-01-mac-fixer.rsc 2 | 3 | # Let's create function to remove colon characters 4 | # from a MAC address passed as an argument 5 | 6 | # --- start of function --- 7 | :global MacColonRemoveFunc do={ 8 | :local TidyMac ""; 9 | for CharNumber from=0 to=([:len $1]-1) do={ 10 | :local TmpValue [:pick $1 $CharNumber]; 11 | :if ($TmpValue !=":") do={ :set TidyMac "$TidyMac$TmpValue" } 12 | } 13 | :return $TidyMac; 14 | } 15 | # --- end of function --- 16 | 17 | # Now, let's call the function with some values 18 | :local MacAddress "00:08:EF:44:98:18" 19 | :put ("$MacAddress becomes: " . [$MacColonRemoveFunc $MacAddress]); 20 | 21 | :set MacAddress "DC:2C:6E:DF:D5:F6" 22 | :put ("$MacAddress becomes: " . [$MacColonRemoveFunc $MacAddress]); 23 | 24 | # Cleanup global namespace 25 | :set MacColonRemoveFunc; 26 | -------------------------------------------------------------------------------- /scripts/v7/ch9-02-mutiple-args-simple.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch9-02-multiple-args-simple.rsc 2 | 3 | # Let's create function to receive multiple args 4 | 5 | # --- start of function --- 6 | :global PrintInterfaceAttrsFunc do={ 7 | 8 | :local InterfaceName $1; 9 | :local InterfaceSpeed $2; 10 | :local InterfaceIp $3; 11 | 12 | # check args are correct data types 13 | if ([:typeof $InterfaceName] != "str") do={ 14 | :error "Interface name argument not a string!"; 15 | } 16 | 17 | if ([:typeof $InterfaceSpeed] != "str") do={ 18 | :error "InterfaceSpeed argument not a string!"; 19 | } 20 | 21 | if ([:typeof $InterfaceIp] != "str") do={ 22 | :error "Interface IP argument not a string!"; 23 | } 24 | 25 | # data type checks passed, print the interface data 26 | :put "$InterfaceName: IP address = $InterfaceIp, speed = \ 27 | $InterfaceSpeed"; 28 | 29 | } 30 | # --- end of function --- 31 | 32 | # Let's call the function with some sample values ($1, $2, $3) 33 | $PrintInterfaceAttrsFunc "WAN1" "100Mbps" "192.168.99.1/24"; 34 | 35 | # Let's call the function with some other values ($1, $2, $3) 36 | $PrintInterfaceAttrsFunc "ether2-LAN" "1000Mbps" "172.16.1.254/24"; 37 | 38 | # Cleanup global namespace 39 | :set PrintInterfaceAttrsFunc; 40 | 41 | -------------------------------------------------------------------------------- /scripts/v7/ch9-03-mutiple-args-array.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch9-03-multiple-args-array.rsc 2 | 3 | # Let's create function to receive a single array arg 4 | 5 | # --- start of function --- 6 | :global PrintInterfaceAttrsFunc do={ 7 | 8 | # verify arg is correct type 9 | if ([:typeof $1] != "array") do={ 10 | :error "Function argument is not an array!"; 11 | } 12 | 13 | # extract values from array passed as arg 14 | :local Args $1; 15 | :local InterfaceName ($Args->"ifname"); 16 | :local InterfaceSpeed ($Args->"ifspeed"); 17 | :local InterfaceIp ($Args->"ifip"); 18 | 19 | # check args are correct data types 20 | if ([:typeof $InterfaceName] != "str") do={ 21 | :error "InterfaceName argument not a string!"; 22 | } 23 | 24 | if ([:typeof $InterfaceSpeed] != "str") do={ 25 | :error "InterfaceSpeed argument not a string!"; 26 | } 27 | 28 | if ([:typeof $InterfaceIp] != "str") do={ 29 | :error "InterfaceIp argument not a string!"; 30 | } 31 | 32 | # data type checks passed, print the interface data 33 | :put "$InterfaceName: IP address = $InterfaceIp, speed = \ 34 | $InterfaceSpeed"; 35 | } 36 | # --- end of function --- 37 | 38 | # Let's call the function with some sample values in an array 39 | :local Args { ifname="WAN1"; ifspeed="100Mbps"; \ 40 | ifip="192.168.99.1/24" }; 41 | $PrintInterfaceAttrsFunc $Args; 42 | 43 | # Let's call the function with some other values in an array 44 | :set Args { ifname="ether2-LAN"; ifspeed="1000Mbps"; \ 45 | ifip="172.16.1.254/24" }; 46 | $PrintInterfaceAttrsFunc $Args; 47 | 48 | # Cleanup global namespace 49 | :set PrintInterfaceAttrsFunc; 50 | -------------------------------------------------------------------------------- /scripts/v7/ch9-04-create-global-func.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch9-04-create-global-func.rsc 2 | 3 | # function to remove spaces from a string 4 | # 5 | # e.g. :local NoSpaceVar [$RemoveSpaceFunc "string with spaces"] 6 | # 7 | :global RemoveSpaceFunc do={ 8 | :local NewName "" 9 | for CharNumber from=0 to=([:len $1]-1) do={ 10 | :local Tmp [:pick $1 $CharNumber] 11 | :if ($Tmp !=" ") do={ :set NewName "$NewName$Tmp" } 12 | } 13 | :return $NewName 14 | } 15 | # --- end of function --- -------------------------------------------------------------------------------- /scripts/v7/ch9-05-use-global-func.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch9-05-use-global-func.rsc 2 | 3 | # declare the name of the global function we wish to use 4 | # to make it available in our script 5 | :global RemoveSpaceFunc; 6 | 7 | # creates a string that contains spaces 8 | :local StringWithSpaces "txBroadcast = 201"; 9 | 10 | # print original string 11 | :put ("String with spaces: $StringWithSpaces"); 12 | 13 | # print string that is modified by function 14 | :local StringNoSpaces [$RemoveSpaceFunc $StringWithSpaces]; 15 | :put ("String with no spaces: $StringNoSpaces"); 16 | -------------------------------------------------------------------------------- /scripts/v7/ch9-06-str-funcs-mod.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch9-06-str-funcs-mod.rsc 2 | 3 | # function to remove spaces from a string 4 | # 5 | # e.g. :local NoSpaceVar [$RemoveSpaceFunc "string with spaces"] 6 | # 7 | :global RemoveSpaceFunc do={ 8 | :local NewName "" 9 | for CharNumber from=0 to=([:len $1]-1) do={ 10 | :local Tmp [:pick $1 $CharNumber] 11 | :if ($Tmp !=" ") do={ :set NewName "$NewName$Tmp" } 12 | } 13 | :return $NewName 14 | } 15 | # --- end of function --- 16 | 17 | # function to remove last char from a string 18 | # 19 | # e.g. :local ChoppedVar [$ChopStrFunc "string with extra char,"] 20 | # 21 | :global ChopStrFunc do={ 22 | :return [ :pick $1 0 ( [ :len $1 ] -1 ) ]; 23 | } 24 | # --- end of function --- -------------------------------------------------------------------------------- /scripts/v7/ch9-07-use-str-module.rsc: -------------------------------------------------------------------------------- 1 | # filename: ch9-07-use-str-module.rsc 2 | 3 | # import the functions we need and declare the functions 4 | # names we wish to use 5 | /import "ch9-06-str-funcs-mod.rsc" 6 | :global RemoveSpaceFunc; 7 | :global ChopStrFunc; 8 | 9 | # check our function names are valid 10 | if ([:typeof $RemoveSpaceFunc] != "array") do={ 11 | :error "RemoveSpaceFunc is wrong data type or does not exist."; 12 | } 13 | 14 | if ([:typeof $ChopStrFunc] != "array") do={ 15 | :error "ChopStrFunc is wrong data type or does not exist."; 16 | } 17 | 18 | # create a string to use with the functions 19 | :local StringToModify "txBroadcast = 201,"; 20 | 21 | # print original string 22 | :put ("Orignal string: $StringToModify"); 23 | 24 | # use both functions to modify the string 25 | :local ModifiedString [$RemoveSpaceFunc $StringToModify]; 26 | :set ModifiedString [$ChopStrFunc $ModifiedString]; 27 | :put ("Modified string: $ModifiedString"); 28 | 29 | # tidy up the global namespace (optional) 30 | :set RemoveSpaceFunc; 31 | :set ChopStrFunc; 32 | --------------------------------------------------------------------------------