HSR Sector 6 · Bangalore +91 96110 27980 Mon–Sat · 09:30–20:30
Chapter 8 of 20 — Python for Network Engineers
intermediate Chapter 8 of 20

Netmiko & Paramiko — SSH Automation for Network Devices

By Vikas Swami, CCIE #22239 | Updated Mar 2026 | Free Course

Paramiko — Low-Level SSH Library for Custom Connections

Paramiko is a foundational Python library that provides an implementation of the SSHv2 protocol, enabling developers to establish secure, encrypted connections to remote machines. As a low-level SSH library, Paramiko offers granular control over SSH sessions, making it suitable for creating custom automation scripts for network engineers who need fine-tuned command execution, file transfers, or session management.

Unlike higher-level libraries, Paramiko does not abstract away the complexity of SSH communication. Instead, it exposes a detailed API that allows you to handle transport, authentication, command execution, and channel management directly. This level of control is especially useful when automating tasks such as deploying configuration files, collecting device information, or scripting interactive sessions on network devices.

For example, to connect to a Cisco router via Paramiko, you initiate an SSH client, load your credentials, and establish a session like this:

import paramiko

ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# Connect to device
ssh_client.connect(hostname='192.168.1.1', username='admin', password='password')

# Open a session
stdin, stdout, stderr = ssh_client.exec_command('show running-config')
output = stdout.read().decode()

print(output)

# Close connection
ssh_client.close()

This approach is flexible but requires handling nuances such as prompt detection, interactive command sequences, and error handling manually. For network engineers aiming for more straightforward, device-specific automation, higher-level libraries like Netmiko simplify these interactions while still leveraging Paramiko’s secure SSH foundation.

Netmiko — High-Level Library Built for Network Devices

Netmiko is a Python library built on top of Paramiko, designed explicitly for network device automation. It abstracts many of the complexities involved in SSH management, providing a simplified API tailored for network engineers working with Cisco, Juniper, Arista, and other network devices. Unlike raw Paramiko, Netmiko offers device-specific behaviors, command parsing, and prompt recognition out of the box, making automation tasks faster and more reliable.

Key features of Netmiko include:

  • Device-specific command handling and prompt recognition
  • Automatic handling of enable mode for privileged EXEC commands
  • Built-in methods for sending configuration sets and retrieving outputs
  • Support for multiple device types with minimal code changes
  • Robust error handling and connection management

For example, connecting to a Cisco IOS device and retrieving its interface status becomes straightforward:

from netmiko import ConnectHandler

cisco_device = {
    'device_type': 'cisco_ios',
    'host': '192.168.1.1',
    'username': 'admin',
    'password': 'password',
    'secret': 'enable_password',  # For privileged EXEC mode
}

net_connect = ConnectHandler(**cisco_device)
net_connect.enable()  # Enter privileged mode

output = net_connect.send_command('show ip interface brief')
print(output)

net_connect.disconnect()

This high-level approach reduces development time, minimizes errors, and supports robust scripting, making it ideal for network device automation. When combined with Networkers Home’s comprehensive courses, you can master Netmiko Paramiko SSH automation to streamline your network management tasks effectively.

Connecting to Cisco, Juniper & Arista Devices via Netmiko

Netmiko simplifies connecting to various network devices by providing device-specific classes and connection parameters. Supporting over 50 device types, it handles differences in CLI, prompts, and authentication mechanisms seamlessly. Here’s a detailed look at connecting to popular devices like Cisco, Juniper, and Arista using Netmiko:

Connecting to Cisco Devices

Most Cisco devices run IOS, IOS-XE, or NX-OS, which share similar command-line interfaces. Using Netmiko, establishing a connection involves specifying the device type and credentials:

from netmiko import ConnectHandler

cisco_ios = {
    'device_type': 'cisco_ios',
    'host': '192.168.1.10',
    'username': 'admin',
    'password': 'password',
    'secret': 'enable_password',  # Enable password for privileged mode
}

net_connect = ConnectHandler(**cisco_ios)
net_connect.enable()
# Now, you can execute commands
output = net_connect.send_command('show version')
print(output)
net_connect.disconnect()

Connecting to Juniper Devices

Juniper devices primarily run Junos OS, which has a different CLI style. Netmiko manages Juniper connections with the 'juniper' device type:

juniper_device = {
    'device_type': 'juniper',
    'host': '192.168.1.20',
    'username': 'juniper_user',
    'password': 'juniper_pass',
}

net_connect = ConnectHandler(**juniper_device)
# Juniper doesn't require enable mode
output = net_connect.send_command('show version')
print(output)
net_connect.disconnect()

Connecting to Arista Devices

Arista EOS devices emulate Cisco’s CLI, making them compatible with 'cisco_ios' device type in Netmiko. A typical connection looks like:

arista_device = {
    'device_type': 'cisco_ios',  # Despite being Arista, 'cisco_ios' works due to CLI similarity
    'host': '192.168.1.30',
    'username': 'admin',
    'password': 'password',
}

net_connect = ConnectHandler(**arista_device)
output = net_connect.send_command('show version')
print(output)
net_connect.disconnect()

Comparison Table of Device Connections:

Device Type Supported OS Device Type String in Netmiko Notes
Cisco IOS IOS, IOS-XE cisco_ios Most common, widely supported
Juniper Junos Junos OS juniper Different CLI, no enable mode needed
Arista EOS EOS cisco_ios CLI similar to Cisco IOS

By mastering these connection techniques, network engineers can automate device management tasks across diverse hardware platforms efficiently. For students enrolled at Networkers Home, learning how to connect and automate multiple device types enhances their skillset significantly in network automation.

Sending Commands — send_command vs send_config_set

Netmiko provides two core methods for executing commands on network devices: send_command and send_config_set. Understanding their differences is critical for effective network device automation.

send_command

The send_command method is used to execute a single CLI command and retrieve its output. It’s suitable for operational commands such as show commands, diagnostic queries, and status checks. This method waits for the device prompt to appear before returning, ensuring the command has completed execution.

output = net_connect.send_command('show interfaces status')

It supports optional parameters like expect_string for prompt customization, delay_factor for adjusting wait times, and max_loops to prevent infinite loops.

send_config_set

The send_config_set method is tailored for pushing configuration commands to network devices. It accepts a list or multiline string of configuration commands, enters configuration mode, executes them sequentially, and exits configuration mode automatically. This simplifies bulk configuration tasks such as VLAN setups, interface configurations, or routing protocol adjustments.

config_commands = [
    'interface GigabitEthernet0/1',
    'description Server Link',
    'switchport mode access',
    'switchport access vlan 10'
]
net_connect.send_config_set(config_commands)

Additionally, send_config_set handles command confirmation prompts and can include delay options to synchronize with device responses. Combining these methods allows for comprehensive automation workflows managing both operational and configuration tasks reliably.

Handling Prompts, Delays & Enable Mode

Effective network automation with Netmiko hinges on proper handling of device prompts, command delays, and privilege levels. Devices often prompt for confirmation, password re-entry, or display different prompts based on mode. Recognizing and managing these prompts ensures automation scripts run smoothly.

Prompt Recognition

Netmiko automatically detects device prompts based on the device type, but custom prompts or unusual configurations may require manual adjustment. The expect_string parameter in send_command helps specify the expected prompt, preventing premature termination.

output = net_connect.send_command('reload', expect_string='Are you sure you want to reload?')

Delays & Timing

Network devices may respond slowly or have commands that require additional time. The delay_factor parameter adjusts the wait time dynamically, ensuring commands are fully executed before responses are processed. For example:

output = net_connect.send_command('show run', delay_factor=2)

Entering Enable Mode

Many privileged commands require entering enable mode. Netmiko simplifies this with the enable() method, which sends the enable password and switches the session to privileged EXEC mode. Proper use of this method is essential for executing configuration commands or retrieving sensitive information.

net_connect.enable()
output = net_connect.send_command('show running-config')

Handling prompts and delays meticulously ensures that your automation scripts are resilient, reducing failures and enabling seamless network device management.

Multi-Device Automation — Looping Through an Inventory

Managing multiple network devices efficiently requires looping through device inventories, establishing sessions, executing commands, and handling errors gracefully. Using Netmiko, this process becomes straightforward, enabling network engineers to automate tasks like backups, updates, and audits across large networks.

Creating an Inventory List

Start with a list or CSV file containing device connection details:

devices = [
    {
        'device_type': 'cisco_ios',
        'host': '192.168.1.10',
        'username': 'admin',
        'password': 'password',
        'secret': 'enable_password',
    },
    {
        'device_type': 'juniper',
        'host': '192.168.1.20',
        'username': 'juniper_user',
        'password': 'juniper_pass',
    },
    # Add more devices as needed
]

Looping and Error Handling

Implement a try-except block to catch connection issues, timeouts, or command failures. For example, to backup configurations from multiple devices:

from netmiko import ConnectHandler

for device in devices:
    try:
        net_connect = ConnectHandler(**device)
        if 'secret' in device:
            net_connect.enable()
        config = net_connect.send_command('show running-config')
        filename = f"{device['host']}_backup.txt"
        with open(filename, 'w') as f:
            f.write(config)
        print(f"Backup successful for {device['host']}")
        net_connect.disconnect()
    except Exception as e:
        print(f"Failed to connect to {device['host']}: {e}")

Benefits of Automated Multi-Device Management

  • Time savings by executing bulk tasks simultaneously
  • Reduced manual errors in repetitive tasks
  • Consistent configuration management across the network
  • Easy integration with scheduling tools like cron or Windows Task Scheduler

Enrolling in courses at Networkers Home provides hands-on training in such automation techniques, empowering network professionals to optimize large-scale network operations effectively.

Concurrent Connections — Threading & concurrent.futures

For large networks, establishing multiple SSH sessions simultaneously is essential to improve efficiency. Python's threading module and concurrent.futures library facilitate concurrent execution, enabling multiple device connections to run in parallel.

Implementing Threading with Netmiko

import threading
from netmiko import ConnectHandler

def backup_device(device):
    try:
        net_connect = ConnectHandler(**device)
        if 'secret' in device:
            net_connect.enable()
        config = net_connect.send_command('show running-config')
        filename = f"{device['host']}_backup.txt"
        with open(filename, 'w') as f:
            f.write(config)
        print(f"Backup completed for {device['host']}")
        net_connect.disconnect()
    except Exception as e:
        print(f"Error with {device['host']}: {e}")

threads = []
for device in devices:
    t = threading.Thread(target=backup_device, args=(device,))
    threads.append(t)
    t.start()

for t in threads:
    t.join()

Using concurrent.futures for Simplicity

import concurrent.futures

def backup(device):
    # Same function as above
    ...

with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
    executor.map(backup, devices)

This approach significantly reduces execution time, especially when managing large inventories. It also improves fault tolerance, as individual device failures do not halt the entire process.

Mastering concurrent execution with Networkers Home can elevate your automation capabilities, making your network management scalable and efficient.

Practice: Backup Running Config from 10 Devices Automatically

Automating configuration backups is a common requirement in network management. Here’s a comprehensive example that combines multi-device looping, threading, and error handling to backup the running-config from 10 devices automatically:

import threading
from netmiko import ConnectHandler

devices = [
    {'device_type': 'cisco_ios', 'host': '192.168.1.10', 'username': 'admin', 'password': 'pass', 'secret': 'enablepass'},
    {'device_type': 'cisco_ios', 'host': '192.168.1.11', 'username': 'admin', 'password': 'pass', 'secret': 'enablepass'},
    # Add up to 10 devices
]

def backup_config(device):
    try:
        net_connect = ConnectHandler(**device)
        net_connect.enable()
        config = net_connect.send_command('show running-config')
        filename = f"{device['host']}_running_config.txt"
        with open(filename, 'w') as f:
            f.write(config)
        print(f"Successfully backed up {device['host']}")
        net_connect.disconnect()
    except Exception as e:
        print(f"Error backing up {device['host']}: {e}")

threads = []
for device in devices:
    t = threading.Thread(target=backup_config, args=(device,))
    threads.append(t)
    t.start()

for t in threads:
    t.join()

print("All device backups completed.")

This script ensures efficient, reliable, and repeatable backups across multiple devices, reducing manual effort and ensuring configuration integrity. For detailed tutorials and practical exercises, visit the Networkers Home Blog for more insights and step-by-step guides.

Key Takeaways

  • Paramiko provides low-level SSH functionalities, offering granular control over SSH sessions for custom network automation scripts.
  • Netmiko builds upon Paramiko, delivering a high-level, device-specific API that simplifies SSH automation for network devices across various vendors.
  • Connecting to Cisco, Juniper, and Arista devices is straightforward with Netmiko; understanding device types and prompts ensures reliable automation.
  • Distinguishing between send_command and send_config_set is crucial for operational vs. configuration tasks.
  • Handling prompts, delays, and privilege levels is vital for robust scripting, preventing hangs and errors.
  • Looping through device inventories with error handling enables scalable network automation across large environments.
  • Implementing concurrency with threading or concurrent.futures accelerates multi-device management tasks.

Frequently Asked Questions

What is the main difference between Paramiko and Netmiko?

Paramiko is a low-level SSH library that provides the core functionality to establish secure SSH connections and execute commands. It offers granular control but requires manual handling of prompts, command sequences, and device-specific behaviors. Netmiko, on the other hand, is a high-level library built on top of Paramiko, specifically designed for network device automation. It abstracts many complexities, providing device-specific commands, prompt recognition, and simplified methods like send_command and send_config_set. This makes Netmiko ideal for network engineers seeking efficient, reliable automation scripts without delving into SSH protocol details.

How can I automate backups of multiple network devices using Netmiko?

To automate backups, create a list of device dictionaries containing connection details. Use a loop or threading to connect to each device, enter enable mode if necessary, execute show running-config with send_command, and save the output to a file named after the device's IP or hostname. Incorporating error handling ensures robustness. You can enhance this by using Networkers Home courses to learn best practices for large-scale automation, scripting, and scheduling backups regularly to maintain network security and compliance.

Can Netmiko handle different vendor devices in a single script?

Yes, Netmiko supports over 50 device types, including Cisco, Juniper, Arista, HP, and more. You specify the device type in your connection parameters, and Netmiko manages the differences internally. For mixed environments, write a flexible script with conditional logic based on device type, or maintain a list of device dictionaries with appropriate device_type entries. This versatility makes Netmiko an essential tool for network engineers managing heterogeneous networks, and training at Networkers Home can prepare you to handle multi-vendor automation seamlessly.

Ready to Master Python for Network Engineers?

Join 45,000+ students at Networkers Home. CCIE-certified trainers, 24x7 real lab access, and 100% placement support.

Explore Course