A 2 AM Phone Call and the Nightmare of “Manual SSH”
The phone screen lights up, vibrating violently on the desk. 2 AM. On the other end, my boss growls: “The South branch VLAN is completely down, get in and fix it now, customers are blowing up our phones!”. I bolt upright, bleary-eyed, and log into the VPN. Before me are 50 Cisco switches and 10 Juniper routers waiting for immediate configuration changes.
Doing it manually means SSHing into each one, typing conf t, pasting commands, and running write mem. Each device takes about 3 minutes. With 60 devices, I’d spend 180 minutes typing non-stop like a machine. Meanwhile, services are paralyzed. That’s when it hit me: if I don’t learn how to use Python for automation, I’ll burn out long before I ever get promoted.
My first script was a makeshift 200-liner. After a few “soul-crushing” nights like that one, it grew to over 2000 lines with comprehensive error-handling modules. Today, I’ll share how you can escape the cycle of staying up all night doing repetitive tasks.
Why Choose Netmiko over Paramiko?
Engineers new to Python often start with Paramiko. However, Paramiko is just a pure SSH library. It has no understanding of network device specifics—for instance, the --More-- prompt when viewing long logs, or the need to enter a second password when running enable on Cisco devices.
Netmiko is a powerful helper built on top of Paramiko. It comes with pre-packaged prompt handling and supports over 100 vendors, from Cisco IOS and Arista EOS to Juniper Junos. With Netmiko, you simply define the device and send the commands; the library takes care of the rest.
Environment Setup in 30 Seconds
All you need is a clean Python environment and to run the installation command via pip:
pip install netmiko
Hands-on: Your First Bulk Configuration Script
Suppose you need to change the enable password or create new VLANs for a list of devices. Instead of manual typing, we’ll use a devices.txt file containing the IPs and let Python handle the rest.
1. Defining Device Parameters
Start by declaring parameters as a Python Dictionary. This is the most fundamental structure for keeping your code clean:
from netmiko import ConnectHandler
cisco_device = {
'device_type': 'cisco_ios',
'host': '192.168.1.10',
'username': 'admin',
'password': 'your_password',
'secret': 'enable_password', # Enable password
'port': 22,
}
2. Connecting and Executing Commands
The biggest advantage of Netmiko is the send_config_set() method. It automatically enters configure terminal mode, executes a list of commands, and exits. Very convenient!
def deploy_config(device_info, config_commands):
try:
# Initialize SSH connection
net_connect = ConnectHandler(**device_info)
# Enter enable mode
net_connect.enable()
# Send configuration list
output = net_connect.send_config_set(config_commands)
# Save configuration to NVRAM
net_connect.send_command("write memory")
print(f"[OK] Successfully configured {device_info['host']}")
# Disconnect
net_connect.disconnect()
except Exception as e:
print(f"[Error] Error at {device_info['host']}: {str(e)}")
# Real-world commands: Add VLAN 100 and assign to port 1
commands = [
'vlan 100',
'name ITFROMZERO_NETWORK',
'interface FastEthernet0/1',
'switchport access vlan 100'
]
deploy_config(cisco_device, commands)
Hard-Earned Lessons: Don’t Take “Naive” Code into Production
When scaling my script from 200 to 2000 lines, I realized that functional code only makes up 30%. The other 70% is for error handling. In reality, network devices are often temperamental—some might have hung SSH sessions, others incorrect passwords, or someone else might already be in configuration mode.
Here are 3 things you must add to your scripts to avoid disaster:
- Timeout: Set a wait limit (e.g., 10 seconds). Don’t let your script hang indefinitely when a switch doesn’t respond.
- Logging: Always log to a file. If your boss asks tomorrow, “What command did you run last night that crashed the network?”, you’ll have an audit trail.
- Try-Except: Wrap every connection in an exception handling block. This allows the script to move on to the second device if the first one fails.
Managing Large Device Lists
Instead of hard-coding IPs, read them from an external file. Using the getpass library will also help secure your passwords:
import getpass
# Enter password via terminal to avoid exposing credentials in the code file
password = getpass.getpass("Enter SSH password: ")
with open('switch_list.txt') as f:
for ip in f:
current_device = {
'device_type': 'cisco_ios',
'host': ip.strip(),
'username': 'admin',
'password': password,
}
deploy_config(current_device, commands)
Final Word for Network Engineers
Learning Python can be daunting at first for those used to pure device configuration. But believe me, the feeling of hitting Enter and watching 50 switches configure themselves while you sip coffee is incredible. Automation doesn’t just make your life easier; it helps achieve standardization across the entire network.
Don’t wait for a 2 AM emergency to start learning. Try installing Netmiko today in simulation environments like Eve-NG or GNS3 to see the difference!

