Scheduler not executing my script

Hello there,

I reused a script I found on this forum after some modifications to update the dyndns. The script is working fine, when I go to the script and run it (ie “/system/script> /system/script/run updateDynDNS”).
Now I want to run this script periodically using the scheduler. I have configured a scheduler like this:

/system scheduler
add comment=“Run dyndns update script periodically " interval=3m name=ScheduleDynDNS on-event=”/system script run updateDynDNS" start-time=startup

I also tried to configure it like this:

/system scheduler
add comment="Run dyndns update script periodically " interval=3m name=ScheduleDynDNS on-event=updateDynDNS start-time=startup

The thing is, I can see the scheduler times it ran is increasing, however my script is not being executed (no log entries and the dyndns record isn’t being updated like it is when I manually execute the script). I’m on ROS 7.16 hEX PoE. Anybody got an idea what the issue could be?


My script

/system script
add comment="This scripts updates Joker dyndns" dont-require-permissions=no name=updateDynDNS owner=admin source="#https://wiki.mikrotik.com/wiki/Manual:Tools/Fetch#:~:text=Learn%20how%20to%20use%20the%20/tool%20fetch%20command%20to%20download,\
    \n#Testing:\
    \n#https://svc.joker.com/nic/update\?username=XXX&password=XXX&hostname=XXX&myip=1.1.1.1\
    \n#dig +short XXX @x.ns.joker.com\
    \n\
    \n# Set needed variables\
    \n:local username \"XXX\"\
    \n:local password \"XXX\"\
    \n:local hostname \"XXX"\
    \n\
    \n:global dyndnsForce\
    \n\
    \n\
    \n# get your public IP\
    \n:local result [/tool fetch mode=https url=https://ipv4.svc.joker.com/nic/myip as-value output=user];\
    \n:local resultData (\$result->\"data\")\
    \n\
    \n# parse the current IP result (grab first line)\
    \n:local currentIP [:pick \$resultData 0 [:find \$resultData \"\\n\"]]\
    \n#:log info \"UpdateDynDNS: currentIP = \$currentIP\"\
    \n\
    \n#resolve the DNS record\
    \n:local resolvedip [:resolve \$hostname]\
    \n\
    \n\
    \n#uncomment line below to force dyndns update, beware of blacklisting by DNS\
    \n#:set dyndnsForce true\
    \n\
    \n#If DNS record is different from my public IP OR dyndnsForce is true; update DNS record through dyndns\
    \n:if ((\$currentIP != \$resolvedip) || (\$dyndnsForce = true)) do={\
    \n:set dyndnsForce false\
    \n:log info \"UpdateDynDNS: Dyndns update needed. PublicIP: \$currentIP ResolvedIP: \$resolvedip\"\
    \n:local dyndns [/tool fetch mode=https url=\"https://svc.joker.com/nic/update\?username=\$username&password=\$password&hostname=\$hostname\" as-value output=user];\
    \n:local dyndnsres (\$dyndns->\"data\")\
    \n:local strippedResult [:pick \$dyndnsres 0 [:find \$dyndnsres \"\\n\"]]\
    \n:log info (\"UpdateDynDNS: Dyndns Update Result: \".\$strippedResult)\
    \n} else={\
    \n:log info (\"UpdateDynDNS: No dyndns update needed\")\
    \n}"

Don’t paste and run scripts that you “found on the internet”, it is dangerous.
Start by pasting only the script in the console. Does it work there? It won’t and you will see why.

you have copied all kinds of random characters and linebreaks (\n), the script has to look something like this:

:local username "name"
:local password "pass"
:local hostname "host.com"
:global dyndnsForce

It may be permissions (fetch specifically, see docs on /system/script). One tip in scheduler you can use just “on-event=ScheduleDynDNS” to run a script, without the /system/script/run part.

Another approach is /ip/cloud – that avoid scripting. You can use CNAME at in your hosted DNS, to keep your desired domain… and your CNAME points, to the Mikrotik’s DDNS name. You can enable the internal DDNS using:
/ip/cloud/set ddns-enabled=yes
and see the DNS name assigned using:
:put [/ip/cloud/get dns-name]
and the IP used:
:put [/ip/cloud/get public-address]

/ip/cloud will do the DDNS, and if you use a CNAME (alias) in your DNS hosting account to point the XXXXX.sn.mynetname.net assigned.

This is typically easier than scripting DDNS, and safer.

But the formatting…

It’s actually RouterOS’s :export that add those “random characters” and lousy linebreaks… maybe someone can clean that up :wink:

I have modified the script and understand what it is doing. I also noted that the script is working fine when run manually.

I will look further into this, but I was assuming as the script doesn’t need permissions to run manually I thought that would not be the issue. But I will check again.
I know we can also execute it by just specifying the name of the script in the scheduler, I actually tried both ways, but neither of them worked.

Regarding the Mikrotik ddns cloud, that’s a valid point. However I would like to try it with the script as well, just to give it a try.

Here is the script again without all the ugly chars added by the export :wink:

# Set needed variables
:local username "XXX"
:local password "XXX"
:local hostname "XXX"

:global dyndnsForce


# get your public IP
:local result [/tool fetch mode=https url=https://ipv4.svc.joker.com/nic/myip as-value output=user];
:local resultData ($result->"data")

# parse the current IP result (grab first line)
:local currentIP [:pick $resultData 0 [:find $resultData "\n"]]
#:log info "UpdateDynDNS: currentIP = $currentIP"

#resolve the DNS record
:local resolvedip [:resolve $hostname]


#uncomment line below to force dyndns update, beware of blacklisting by DNS
#:set dyndnsForce true

#If DNS record is different from my public IP OR dyndnsForce is true; update DNS record through dyndns
:if (($currentIP != $resolvedip) || ($dyndnsForce = true)) do={
:set dyndnsForce false
:log info "UpdateDynDNS: Dyndns update needed. PublicIP: $currentIP ResolvedIP: $resolvedip"
:local dyndns [/tool fetch mode=https url="https://svc.joker.com/nic/update?username=$username&password=$password&hostname=$hostname" as-value output=user];
:local dyndnsres ($dyndns->"data")
:local strippedResult [:pick $dyndnsres 0 [:find $dyndnsres "\n"]]
:log info ("UpdateDynDNS: Dyndns Update Result: ".$strippedResult)
} else={
:log info ("UpdateDynDNS: No dyndns update needed")
}

edit:
I checked manual for user/usergroups (https://help.mikrotik.com/docs/display/ROS/User):

test - policy that grants rights to run ping, traceroute, bandwidth-test, wireless scan, snooper, fetch, email and other test commands

The script manual, doesn’t state the fetch with the test policy (https://wiki.mikrotik.com/wiki/Manual:Scripting#:~:text=Learn%20how%20to%20use%20RouterOS%20built-in%20scripting%20language%20to%20automate):

test - can run ping, traceroute, bandwidth test

So maybe I need the test policy. I will look into this. Thanks

edit2:
I added the test policy to the script and the scheduler, but still the same result. The script does not get executed by the scheduler.

As a second test I added all polcies to the script and the scheduler. And suddenly it start working. I have no idea what policy it is that I require. But it is interesting imo. Also as I said before. The script works without checking any policies when I manually run it.

edit3:
I added the Read and Test Policy on the scheduler and then it works. No policies were added on the script.
I don’t really understand tho why I need the read and test policy.

Also, when I specify the script like this, it doesn’t work:

/system scheduler
add comment="Run dyndns update script periodically " interval=10s name=ScheduleDynDNS on-event=updateDynDNS policy=read,test start-time=startup

Like this it does work for some reason:

/system scheduler
add comment="Run dyndns update script periodically " interval=10s name=ScheduleDynDNS on-event="/system script run updateDynDNS" policy=read,test start-time=startup