Building a custom Telnet scripts runner allows you to automate repetitive tasks across legacy Cisco switches. While Netmiko and Paramiko are standard libraries for this, Python’s built-in telnetlib was deprecated and removed in Python 3.13.
To build a modern, future-proof Telnet runner, you should use Exscript, Netmiko (via its Telnet helper), or the third-party telnetlib3 library.
Here is a step-by-step guide to building a custom Telnet runner using Netmiko, which handles Cisco-specific command prompts and paging (–More–) automatically. Prerequisites Install Netmiko via your terminal: pip install netmiko Use code with caution. 1. Structure Your Project
Create three separate files to keep your automation clean and reusable: switches.txt: Stores your IP addresses.
commands.txt: Stores the Cisco iOS commands you want to run. runner.py: The main Python script. 2. Prepare Your Input Files switches.txt 192.168.1.10 192.168.1.11 Use code with caution. commands.txt show ip interface brief show version Use code with caution. 3. Write the Custom Runner Script
Here is a complete, scalable script that reads your inputs, connects via Telnet, executes the commands, and saves the output to log files.
import os from netmiko import ConnectHandler from netmiko.exceptions import NetmikoTimeoutException, NetmikoAuthenticationException # 1. Define credentials and configuration USERNAME = “admin” PASSWORD = “YourPassword123” SECRET = “YourEnablePassword” # Optional: For enable mode def read_file_lines(filename): “”“Helper to read lines from a file, ignoring empty lines.”“” if not os.path.exists(filename): print(f”Error: {filename} not found.“) return [] with open(filename, “r”) as f: return [line.strip() for line in f if line.strip()] def run_telnet_script(): # 2. Load targets and instructions devices = read_file_lines(“switches.txt”) commands = read_file_lines(“commands.txt”) if not devices or not commands: print(“Missing devices or commands. Exiting.”) return # 3. Loop through each switch for ip in devices: print(f” Connecting to {ip} via Telnet…“) # Define the Netmiko device dictionary for Telnet device_config = { “device_type”: “cisco_ios_telnet”, “host”: ip, “username”: USERNAME, “password”: PASSWORD, “secret”: SECRET, “keepalive”: 10, } try: # 4. Establish Telnet session with ConnectHandler(device_config) as net_connect: # Enter enable mode if a secret is provided if SECRET: net_connect.enable() print(f”Successfully connected to {ip}. Running commands…“) output_buffer = [] # 5. Execute commands sequentially for cmd in commands: output_buffer.append(f”=== Command: {cmd} ===“) # send_command handles pagination and prompt matching automatically cmd_output = net_connect.send_command(cmd) output_buffer.append(cmd_output) output_buffer.append(” “) # 6. Save results to a unique log file logfilename = f”output{ip}.txt” with open(log_filename, “w”) as log_file: log_file.write(” “.join(output_buffer)) print(f”Finished {ip}. Output saved to {log_filename}“) except NetmikoTimeoutException: print(f”Error: Connection timed out to {ip}“) except NetmikoAuthenticationException: print(f”Error: Authentication failed for {ip}“) except Exception as e: print(f”An unexpected error occurred for {ip}: {e}“) if name == “main”: run_telnet_script() Use code with caution. Key Enhancements for Production
Threaded Execution: For more than 5 switches, the script will be slow because it runs sequentially. Use Python’s concurrent.futures.ThreadPoolExecutor to run multiple Telnet sessions in parallel.
Error Logging: Implement the logging module to direct errors to a central errors.log file instead of just printing them to the screen.
Configuration Mode: If you want to make configuration changes instead of just running show commands, swap net_connect.send_command(cmd) with net_connect.send_config_set(commands). This automatically handles entering and exiting configure terminal.
If you would like to expand this runner, please let me know:
Do you need to make configuration changes or just gather show data?
How many total switches are you planning to run this against simultaneously?
Do your switches require a secondary Enable password to run these commands?
I can provide the exact code modifications to handle concurrency or configuration blocks based on your needs.
Leave a Reply