Skip to content

RouterOS: Mass Upgrade Firmware Across Multiple Routers

Upgrading RouterOS and RouterBOARD firmware across a fleet of routers manually is error-prone and time-consuming. RouterOS scripting and the scheduler make it possible to automate upgrades across many devices with minimal manual intervention.

There are two distinct upgrade steps on any MikroTik device:

  1. RouterOS package upgrade — installs a new .npk package; takes effect after reboot.
  2. RouterBOARD firmware upgrade — updates the bootloader on the physical board; also requires a reboot and must be done after the RouterOS upgrade.

Both can be scripted and scheduled independently. The safest approach separates download from reboot so that you control when devices go offline.

Warning: Automating reboots across a fleet can cause simultaneous outages if a bad release is installed everywhere at once. Use staged rollout — test a small group first, then widen the window.

  • RouterOS 6.x or later on each device
  • Each router must have internet (or LAN) access to reach the MikroTik update servers, or you must provide a local package mirror
  • Scripts require policy permissions: read, write, policy, test, reboot
  • The update channel must be set to the desired channel (stable, long-term, testing) on every device before automation begins

Set the update channel:

/system package update set channel=stable

Note — entering multiline scripts: RouterOS CLI cannot reliably parse multiline source={...} blocks that contain quotes, dots, or nested braces. The script bodies below work correctly when entered via one of these methods:

WinBox / WebFig: Go to System → Scripts → Add, paste the script body (the content inside { }) into the Source field, set the name and policy, then click OK.

File import: Save the full /system script add ... command to a .rsc file, copy it to the router with /tool fetch or SCP, then run /import file-name=upgrade-scripts.rsc.

The scheduler commands at the end of each section are single-line and can be entered directly in the CLI terminal.

Section titled “Method 1: Scheduled Script (Recommended for Unattended Fleets)”

This two-script approach separates the download from the reboot. Script 1 runs nightly, checks for updates, and downloads the package if one is available. Script 2 runs shortly after and reboots only if a package was downloaded.

/system script add name=auto-upgrade-check \
policy=read,write,policy,test,reboot \
source={
:local installed [/system package update get installed-version]
/system package update check-for-updates once
:delay 5
:local latest [/system package update get latest-version]
:if ([:len $latest] = 0) do={
:log warning "auto-upgrade: update check returned no version; aborting"
} else={
:if ($installed != $latest) do={
:log info ("auto-upgrade: update available " . $installed . " -> " . $latest . "; downloading")
/system package update download
:delay 5
/system scheduler set [find name=auto-upgrade-reboot] disabled=no
} else={
:log info ("auto-upgrade: already up to date (" . $installed . ")")
}
}
}
/system script add name=auto-upgrade-reboot \
policy=read,write,policy,test,reboot \
source={
:local status [/system package update get status]
:if ($status ~ "Downloaded") do={
:log warning "auto-upgrade: package downloaded; rebooting to install"
/system reboot
} else={
:log info ("auto-upgrade: no downloaded package (status=" . $status . "); skipping reboot")
/system scheduler set [find name=auto-upgrade-reboot] disabled=yes
}
}
/system scheduler add name=auto-upgrade-check \
start-time=23:30:00 interval=1d \
on-event=auto-upgrade-check \
policy=read,write,policy,test,reboot
/system scheduler add name=auto-upgrade-reboot \
start-time=00:00:00 interval=1d \
on-event=auto-upgrade-reboot \
policy=read,write,policy,test,reboot \
disabled=yes

The check script runs at 23:30 to allow download to complete before midnight. The reboot script runs at 00:00 but starts disabled; the check script enables it only when a download is ready.

Method 2: RouterBOARD Firmware Upgrade (After RouterOS Upgrade)

Section titled “Method 2: RouterBOARD Firmware Upgrade (After RouterOS Upgrade)”

After the device reboots into the new RouterOS version, the RouterBOARD firmware (bootloader) may be outdated. This is a separate step. Add this script and schedule it to run after the RouterOS upgrade reboot. Enter via WinBox/WebFig or file import (see note above — multiline source fails via CLI):

/system script add name=auto-upgrade-firmware \
policy=read,write,policy,test,reboot \
source={
:local current [/system routerboard get current-firmware]
:local upgrade [/system routerboard get upgrade-firmware]
:if ($current != $upgrade) do={
:log warning ("auto-upgrade-firmware: upgrading bootloader " . $current . " -> " . $upgrade)
/system routerboard upgrade
:delay 3
/system reboot
} else={
:log info ("auto-upgrade-firmware: bootloader already current (" . $current . ")")
}
}

Schedule this to run once at a safe time after the RouterOS reboot window:

/system scheduler add name=auto-upgrade-firmware \
start-time=01:00:00 interval=1d \
on-event=auto-upgrade-firmware \
policy=read,write,policy,test,reboot

Method 3: Package Push via /tool fetch (LAN Mirror)

Section titled “Method 3: Package Push via /tool fetch (LAN Mirror)”

For sites without direct internet access, or to avoid every router downloading independently, upload the .npk file to a local HTTP server and have routers fetch it:

/tool fetch url="http://192.168.1.100/packages/routeros-7.x.x-arm64.npk" \
dst-path=routeros-7.x.x-arm64.npk
/system reboot

Wrap this in a script and push it to all routers via SSH or the MikroTik API in a maintenance window.

Method 4: SSH/API Loop from a Management Host

Section titled “Method 4: SSH/API Loop from a Management Host”

For large fleets, an SSH or API loop from a central host gives the most control. A shell loop or Ansible playbook can:

  1. Check current version on each router
  2. Upload the .npk package
  3. Trigger reboot
  4. Verify the new version post-reboot before proceeding to the next device

This avoids simultaneous reboots and allows per-device validation.

After an automated upgrade cycle, check that the expected version is running:

/system package print

Verify RouterBOARD firmware is current:

/system routerboard print

Both current-firmware and upgrade-firmware should show the same value if the bootloader upgrade completed successfully.

Check the system log for upgrade events:

/log print where topics~"system"

Script does not trigger reboot even though an update is available

The status field returned by /system package update get status varies between RouterOS versions. Print the value directly to see the exact string on your version:

/system package update check-for-updates once
:delay 5
:put [/system package update get status]

Adjust the $status ~ "Downloaded" match in the reboot script to match the actual string your version returns.

Routers on different architectures fail to install a package

Each router architecture (arm, arm64, x86, mipsbe, etc.) requires a matching .npk file. When pushing packages from a central server, ensure the correct architecture variant is delivered to each device. The built-in update channel (/system package update) handles this automatically; manual pushes do not.

RouterBOARD firmware upgrade fails silently

Some CHR (Cloud Hosted Router) instances do not have physical RouterBOARD firmware and will show identical current-firmware and upgrade-firmware values. The firmware upgrade script is a no-op on these devices, which is correct behaviour.

Reboot window causes overlapping outages

Stagger scheduler start times across devices. RouterOS has no built-in random number function, so assign a unique start-time per router during initial provisioning. For example, when pushing config via SSH or API, derive the offset from the device index or last octet of its management IP:

# On router 1: start at 23:00
/system scheduler set [find name=auto-upgrade-check] start-time=23:00:00
# On router 2: start at 23:15
/system scheduler set [find name=auto-upgrade-check] start-time=23:15:00
# On router 3: start at 23:30
/system scheduler set [find name=auto-upgrade-check] start-time=23:30:00

Spread the window to avoid simultaneous downloads and reboots across the fleet.