This is a Python script to send commands to multiple Mikrotik devices via the API. It provides concurrent operations, detailed logging (seamlessly integrated with the progress bar), a formatted job summary, and configurable settings.
This script builds on work already done by Phillip Hutchison and Kevin Byrd, ported to Python and the Mikrotik API by Gabriel Rolland.
Key Features:
- MikroTik API: Uses the
librouteroslibrary to interact with the Mikrotik API. - Concurrent Operation: Employs threading to connect to multiple devices simultaneously. The number of threads is configurable (
--threads). - Progress Bar: Provides a visual progress bar (
tqdm) with live counters (ok/fail). - Structured Logging: Uses Python's standard
loggingmodule.- Detailed logs are saved to a file in the
logdirectory. Each run of the script generates a new log file with a timestamp in its name. File logs include timestamps, log levels, and thread names. - Console output seamlessly integrates with the
tqdmprogress bar to prevent visual glitches, and includes optional color-coding for different log levels (--no-colorsto disable). - Debug mode for more verbose logging (
--debug).
- Detailed logs are saved to a file in the
- Job Summary: At the end of execution, a cleanly formatted visual summary is provided detailing total hosts processed, successful operations, failed operations (including a list of specific failed IPs), and elapsed time. Exit code is
0for all-success,1if any failure occurred. - YAML Configuration File: All CLI options can be specified via a YAML configuration file (
--config). CLI arguments override config file values. - SSL/TLS Support: Optional SSL connections via the MikroTik API-SSL service. Configurable per-host (
|SSLflag in the IP list) or globally (--sslflag). Certificate verification is disabled to support MikroTik's self-signed certificates. - Flexible Host Configuration:
- IP list sourced from a file (default:
list.txt, configurable via--ip-list). - Supports
IP,IP:PORT,IP[:PORT]|USERNAME|PASSWORD, andIP[:PORT][|USERNAME|PASSWORD]|SSLformats in the list file. - Default API port is 8728 (or 8729 when SSL is enabled), configurable via
--port.
- IP list sourced from a file (default:
- Error Handling: Graceful handling of connection errors (
TimeoutError,socket.error,LibRouterosError), API errors, and transient cloud backup issues, with intelligent retries for command execution. Malformed lines in the IP list are skipped with a warning. Error messages include the target IP:port. - Update Logic: Checks for and installs updates by default.
--dry-runmode to simulate without actual installation (indicated in progress bar and summary).- Configurable attempts and delay for update status checking (
--update-check-attempts,--update-check-delay).
- Custom Commands (External): Supports execution of user-defined custom commands loaded from an external YAML file (
--custom-commands). - Secure Password Input: If the password is not provided via command-line or config file, the script will securely prompt for it.
- Graceful Shutdown: Handles
KeyboardInterrupt(Ctrl+C) cleanly. A second Ctrl+C during shutdown is silently caught without traceback. - Start Line: Option to start processing the IP list from a specific line number (
--start-line). - Exit Codes:
0on complete success,1if any host failed or IP list file was not found.
-
Python 3.6 or later
-
librouteroslibrary: (Tested with v3.4.1, other versions might work) -
tqdmlibrary: For the progress bar. -
pyyamllibrary: For loading custom commands and configuration from YAML files.pip install librouteros tqdm pyyaml
or on Debian/Ubuntu (for
librouterosonly,tqdmandpyyamlusually need pip):sudo apt install python3-librouteros pip install tqdm pyyaml
- API access (port 8728 by default, or 8729 for API-SSL) must be enabled on your Mikrotik devices. Use
--sslor the|SSLflag in the IP list for SSL connections. - The log file is created fresh each time the script is run with a timestamp.
- Default connection timeout is 5 seconds (change with
--timeout). The effective minimum is clamped to 30 seconds.
-u USERNAME,--username USERNAME: Specifies the API username. Can be provided via--configinstead of CLI.-p PASSWORD,--password PASSWORD: Specifies the API password. If not provided, the script will securely prompt for it.-t THREADS,--threads THREADS: Number of concurrent threads to use. Default:5.--timeout TIMEOUT: Connection timeout in seconds for API communication. Default:5.--ip-list FILE_PATH: Path to the IP list file. Default:list.txt.--port API_PORT: Default API port if not specified in the IP list file. Default:8728.--update-check-attempts ATTEMPTS: Number of attempts to check update status. Default:15.--update-check-delay DELAY: Delay (seconds) between update status checks. Default:2.0.--no-colors: Disables colored output on the console.--dry-run: Enables dry-run mode (simulates updates but doesn't install).--start-line LINE_NUM: Start from this line number in the IP list file (1-based). Default:1.--debug: Enables debug logging level for more verbose output.--cloud-password PASSWORD: Password for cloud backup. (Required for performing cloud backup)--upgrade-firmware: Perform firmware upgrade.--ssl: Enables SSL/TLS for all connections. When used, the default port switches to8729(API-SSL). SSL can also be enabled per-host by appending|SSLto entries in the IP list file.--custom-commands FILE_PATH: Path to a YAML file containing custom commands to execute on each router.--config FILE_PATH: Path to a YAML configuration file. CLI arguments override config file values.--version: Display version and exit.
-
Download or clone
mkmassupdate.py. -
Install the required libraries (see "Requirements" section).
-
Prepare your IP list file (default
list.txt). -
(Optional) Create a
commands.yamlfile for custom commands (see "Custom Commands File Format" below). -
(Optional) Create a
config.yamlfile to store common options (see "Config File Format" below). -
Run the script with your credentials and desired options:
python3 mkmassupdate.py -u your_username [OPTIONS]
Examples:
-
Basic run (will prompt for password):
python3 mkmassupdate.py -u admin
-
Using a custom IP list and 20 threads with password provided:
python3 mkmassupdate.py -u admin -p pass123 --ip-list /path/to/my_routers.txt -t 20
-
Dry run with increased timeout and debug logging, using custom commands:
python3 mkmassupdate.py -u admin --dry-run --timeout 30 --debug --custom-commands commands.yaml
-
Perform cloud backup with a specified password:
python3 mkmassupdate.py -u admin --cloud-password your_cloud_backup_password
-
Perform firmware upgrade:
python3 mkmassupdate.py -u admin --upgrade-firmware
-
Connect using SSL for all routers:
python3 mkmassupdate.py -u admin --ssl
-
Using a YAML config file (username is read from config):
python3 mkmassupdate.py --config config.yaml
-
A YAML configuration file can be used to set default values for all CLI options. CLI arguments always override equivalent config file values.
Example config.yaml:
username: admin
password: my_secret_password
threads: 10
timeout: 30
port: 8728
ssl: false
ip_list: list.txt
start_line: 1
update_check_attempts: 15
update_check_delay: 2.0
dry_run: false
no_colors: false
debug: false
cloud_password: my_cloud_password
upgrade_firmware: false
custom_commands: commands.yamlKeys are optional. Unknown keys are silently ignored. See config.yaml.example for a commented template.
Custom commands are loaded from an external YAML file specified by the --custom-commands argument. The file should contain a list of command definitions. Each command can be a simple string (for commands without parameters) or an object with command and params keys.
Example commands.yaml:
# Example of custom commands
# Each item is a list containing [path, {parameter_dictionary}] or just [path]
- command: /system/clock/print
- command: /user/add
params:
name: newuser
password: "secure_password_123"
group: read
- command: /ip/firewall/filter/print
params:
"?chain": "input"Note: Parameter names must match MikroTik API specifications.
One entry per line. Supported formats:
-
IP only (uses default API port and script credentials)
192.168.1.1 -
IP with custom port
192.168.1.2:8729 -
IP[:port] with custom credentials (username|password)
192.168.1.3|customuser|custompass 192.168.1.4:8729|customuser2|custompass2 -
IP with SSL (auto-uses port 8729)
192.168.1.5|SSL -
IP[:port] with custom credentials and SSL
192.168.1.6|admin|password123|SSL 192.168.1.7:8730|admin|password123|SSL -
Lines starting with # are comments. Empty lines are ignored.
This script is provided as-is, without warranty of any kind. Use it at your own risk. Always test thoroughly in a non-production environment before deploying to production devices.
GNU General Public License v3.0
Copyright (C) 2026 Rolland Gabriel (https://github.com/rollopack)
