Python: Sending a command to multiple devices via SSH
In the event that you wish to run a single command against multiple network devices from a jump box.
NB: You'll need to install the pexpect Python module for this script to work.
Script:
#!/usr/bin/env python # bulk-ssh-cmd.py (2,000 character output limit per device). # Usage: python bulk-ssh-cmd.py 'command string' '/path/file.txt' # Import required module(s). Only pexpect needs to be downloaded and installed, all others should be present. import sys import os import getpass import pexpect # Validate correct number of command line parameters. argList = sys.argv[1:] if len(argList) 2: sys.exit("Please specify a command string AND a valid source file.") # Set RSA key fingerprint expected output string for new connections. cliCMD = sys.argv[1] ssh_newkey = 'Are you sure you want to continue connecting' # Obtain and read in hosts from file specified in CLI and validate filetype and existence. inputFile = sys.argv[2] print inputFile if not inputFile.endswith(".txt"): sys.exit("Error: %s is not a valid text file." % inputFile) elif os.path.exists(inputFile): hostFile = open(inputFile, "r") else: sys.exit("Error: %s file not found." % inputFile) # Get credentials. userID = os.getenv("USER") openSsme = getpass.getpass(prompt="What is your password? \n") # Handle RSA key fingerprint, login prompt and EOF output. for hostBox in hostFile: # Specify connection string & expected responses. connStr=pexpect.spawn('ssh %s@%s' % (userID, hostBox), timeout = 5) resVal=connStr.expect([ssh_newkey,'assword:',pexpect.EOF]) if resVal==0: print "Sending yes to accept RSA key fingerprint." connStr.sendline('yes') resVal=connStr.expect([ssh_newkey,'assword:',pexpect.EOF]) if resVal==1: print "Password sent. Command:", connStr.sendline(openSsme) connStr.expect("#") connStr.sendline(cliCMD) connStr.expect("#") connStr.sendline("exit") print connStr.before , "\n" # Print the command output. else: print "Key or connection timeout received." pass
Data file (can be IP addresses or hostnames):
admin@linux-host (~/scripts)$ cat hosts.txt 192.168.42.5 192.168.42.6 192.168.42.7
Usage:
python bulk-ssh-cmd.py 'command string' '/path/file.txt'
Error handling:
Too few command line parameters:
admin@linux-host (~/scripts)$ python bulk-ssh-cmd.py 'sh ip int br vrf management' Please specify a command string AND a valid source file.
Too many command line parameters:
admin@linux-host (~/scripts)$ python bulk-ssh-cmd.py 'sh ip int br vrf management' '/home/admin/scripts/hostings.txt' test Please specify a command string AND a valid source file.
Invalid file extension:
admin@linux-host (~/scripts)$ python bulk-ssh-cmd.py 'sh ip int br vrf management' '/home/admin/scripts/test.csv' /home/admin/scripts/test.csv Error: /home/admin/scripts/test.csv is not a valid text file.
Non-existant file:
admin@linux-host (~/scripts)$ python bulk-ssh-cmd.py 'sh ip int br vrf management' '/home/admin/scripts/hostings.txt' /home/admin/scripts/hostings.txt Error: /home/admin/scripts/hostings.txt file not found.
NB: This script will work with Cisco IOS & NX-OS as well as Arista EOS. The lines stating connStr.expect("#") will need to be changed to connStr.expect(">") for Juniper JunOS.















