Originally posted on May 15, 2022 @ 4:34 pm
Run Python Automation Script to fetch Cisco Routers and Switches details in Bulk
Today in this article we will see how to use a python script to get Cisco router and Cisco switch status in bulk. The details includes “hostname, uptime, current version, current image, serial number, device model, device memory”
Pre-Requisite is to install Netmiko. In case you have not installed netmiko, follow our previous post:
Netmiko SSH – Python Automation on Cisco Routers and Switches using SSH
What the script is doing (Trying to explain in very short)?
- The script will login to each IP Address defined in ip_list
- Create 2 files to save the output of the script (fetch data and write to IOS.csv on successful login and write to login_issues.csv on unsuccessful login with reason)
- In case of any exception/error, it will not stop the script, it will write the error/exceptions in login_issues.csv and continue to run the script for the remaining IP Address.
- It will use regex to fetch all the information from router/switch like “uptime, hostname, version, memory, ios, serial, model etc“
- All the data will be appended to devices = []
- Finally it will write the data from devices = [] to IOS.csv file.
Here is the working Python script:
from netmiko import ConnectHandler from netmiko.ssh_exception import NetMikoTimeoutException from netmiko.ssh_exception import SSHException from netmiko.ssh_exception import AuthenticationException import re #here is list of cisco routers ip addresses ip_list = ['192.168.1.50', '192.168.1.51', '192.168.1.52', '192.168.1.60'] #list where informations will be stored devices = [] #clearing the old data from the CSV file and writing the headers f = open("IOS.csv", "w+") f.write("IP Address, Hostname, Uptime, Current_Version, Current_Image, Serial_Number, Device_Model, Device_Memory") f.write("\n") f.close() #clearing the old data from the CSV file and writing the headers f = open("login_issues.csv", "w+") f.write("IP Address, Status") f.write("\n") f.close() #loop all ip addresses in ip_list for ip in ip_list: cisco = { 'device_type':'cisco_ios', 'ip':ip, 'username':'cisco', #ssh username 'password':'cisco', #ssh password 'secret': 'cisco', #ssh_enable_password 'ssh_strict':False, 'fast_cli':False, } #handling exceptions errors try: net_connect = ConnectHandler(**cisco) except NetMikoTimeoutException: f = open("login_issues.csv", "a") f.write(ip + "," + "Device Unreachable/SSH not enabled") f.write("\n") f.close() continue except AuthenticationException: f = open("login_issues.csv", "a") f.write(ip + "," + "Authentication Failure") f.write("\n") f.close() continue except SSHException: f = open("login_issues.csv", "a") f.write(ip + "," + "SSH not enabled") f.write("\n") f.close() continue try: net_connect.enable() #handling exceptions errors except ValueError: f = open("login_issues.csv", "a") f.write(ip + "," + "Could be SSH Enable Password issue") f.write("\n") f.close() continue # execute show version on router and save output to output object sh_ver_output = net_connect.send_command('show version') #finding hostname in output using regular expressions regex_hostname = re.compile(r'(\S+)\suptime') hostname = regex_hostname.findall(sh_ver_output) #finding uptime in output using regular expressions regex_uptime = re.compile(r'\S+\suptime\sis\s(.+)') uptime = regex_uptime.findall(sh_ver_output) uptime = str(uptime).replace(',' ,'').replace("'" ,"") uptime = str(uptime)[1:-1] #finding version in output using regular expressions regex_version = re.compile(r'Cisco\sIOS\sSoftware.+Version\s([^,]+)') version = regex_version.findall(sh_ver_output) #finding serial in output using regular expressions regex_serial = re.compile(r'Processor\sboard\sID\s(\S+)') serial = regex_serial.findall(sh_ver_output) #finding ios image in output using regular expressions regex_ios = re.compile(r'System\simage\sfile\sis\s"([^ "]+)') ios = regex_ios.findall(sh_ver_output) #finding model in output using regular expressions regex_model = re.compile(r'[Cc]isco\s(\S+).*memory.') model = regex_model.findall(sh_ver_output) #finding the router's memory using regular expressions regex_memory = re.search(r'with (.*?) bytes of memory', sh_ver_output).group(1) memory = regex_memory #append results to table [hostname,uptime,version,serial,ios,model] devices.append([ip, hostname[0],uptime,version[0],ios[0], serial[0],model[0], memory]) #print all results (for all routers) on screen for i in devices: i = ", ".join(i) f = open("IOS.csv", "a") f.write(i) f.write("\n") f.close()
Modify the script as per your requirement:
- Modify the ip_list according to your requirement. (See below)
- Modify Username, Password and Secret according to your requirement. (See below)
- Run the python script and it will generate two files upon completion i.e., IOS.csv and login_issues.csv.
- IOS.csv – All the data that will be successfully fetched from the rotuers/switches will be stored here.
- login_issues.csv – All the unsuccessful login (like device unreachable, authentication error) will be captured here.
Here is the output of the Python script execution:
The below screenshot shows the data successfully fetched and the data written to IOS.csv
The below screenshot shows that the login was unsuccessful due to the device not reachable or SSH not enabled or Authentication issues and the reason/error is written in login_issues.csv.
On What devices this script has been tested?
This script has been tested on Cisco 2811, Cisco 2901, Cisco 2911, Cisco 3725, Cisco 3745, Cisco 3825, Cisco 3925, Cisco ISR4221 and ISR4451 and it works perfectly fine.
Would love to hear back from you on what devices you have tested and where it has worked or not worked.
HTH.
I am working in an IT company and having 10+ years of experience into Cisco IP Telephony and Contact Center. I have worked on products like CUCM, CUC, UCCX, CME/CUE, IM&P, Voice Gateways, VG224, Gatekeepers, Attendant Console, Expressway, Mediasense, Asterisk, Microsoft Teams, Zoom etc. I am not an expert but i keep exploring whenever and wherever i can and share whatever i know. You can visit my LinkedIn profile by clicking on the icon below.
“Everyone you will ever meet knows something you don’t.” ― Bill Nye
this isnt very functional if you have to manually add every ip address to the script instead of pulling it from a file
You can always modify the script and create it as per your requirement to read a file.
This is great, thanks for sharing!
I will test on a set of devices and report back here. In the meantime, I had a couple questions.
1. Have you tested the ‘autodetect’ feature in Netmiko? Since there are different device_types for Cisco (cisco_xe, cisco_ASA,..), I was wondering if that would be a good approach to make this script work on many different cisco devices, or will most devices work with “cisco_ios”?
2. I’m trying to expand the script to determine the installed feature sets. One of the commands I’d like to run is ‘show license all’ which gives you an output similar to the below:
device1# sho license usage
Feature Ins Lic Status Expiry Date Comments
Count
——————————————————————————–
MPLS_PKG No – Unused –
STORAGE-ENT No – Unused –
VDC_LICENSES No 0 Unused –
ENTERPRISE_PKG No – Unused –
FCOE-N7K-F132XP No 0 Unused –
FCOE-N7K-F248XP No 0 Unused –
ENHANCED_LAYER2_PKG No – Unused –
SCALABLE_SERVICES_PKG No – Unused –
TRANSPORT_SERVICES_PKG No – Unused –
LAN_ADVANCED_SERVICES_PKG No – Unused –
LAN_ENTERPRISE_SERVICES_PKG Yes – In use Never –
in this example, I’d like to use regular expressions to pull pack the feature that says “Yes” in the 2nd column of the output, but I’m struggling to get that done. Is there a way you could help me with that?
Thanks,
Roland
This is great, thanks for sharing!
I will test on a set of devices and report back here. In the meantime, I had a couple questions.
1. Have you tested the ‘autodetect’ feature in Netmiko? Since there are different device_types for Cisco (cisco_xe, cisco_ASA,..), I was wondering if that would be a good approach to make this script work on many different cisco devices, or will most devices work with “cisco_ios”?
2. I’m trying to expand the script to determine the installed feature sets. One of the commands I’d like to run is ‘show license all’ which gives you an output similar to the below:
device1# sho license usage
Feature Ins Lic Status Expiry Date Comments
Count
——————————————————————————–
MPLS_PKG No – Unused –
STORAGE-ENT No – Unused –
VDC_LICENSES No 0 Unused –
ENTERPRISE_PKG No – Unused –
FCOE-N7K-F132XP No 0 Unused –
FCOE-N7K-F248XP No 0 Unused –
ENHANCED_LAYER2_PKG No – Unused –
SCALABLE_SERVICES_PKG No – Unused –
TRANSPORT_SERVICES_PKG No – Unused –
LAN_ADVANCED_SERVICES_PKG No – Unused –
LAN_ENTERPRISE_SERVICES_PKG Yes – In use Never –
in this example, I’d like to use regular expressions to pull pack the feature that says “Yes” in the 2nd column of the output, but I’m struggling to get that done. Is there a way you could help me with that?
Thanks,
Roland
How can I change the port if I am not using SSH over port 22?
Thank You for the Script, it shure helped me get started. I wanted to post my findings and how it worked for me.
In the original Script you set the code below.
regex_version = re.compile(r’Cisco\sIOS\sSoftware.+Version\s([^,]+)’)
It worked better for me when I added an extra space in the re.compile part like this:
regex_version = re.compile(r’Cisco\sIOS\sSoftware.+Version\s([^ ,]+)’)
In this case I had an Output of only the Version Number instead of the whole CISCO part.
Hi HTH,
Thankyou for your post, It is what exactly I’m looking for. So we have quaterly healthchecks of the our clients network infra where we need to collect all these information and provide our findings. Thankyou. I’m gonna start following your instructions now and will comment back to let you know if I succeeded.
Thankyou once again. Much appreciated.
Works great. Thanks!
helpful. do you have any idea, how to run a python program, where the program reads from a csv file of switches(hostnames),and then logs into them to get nformations like ips of those switches. I could do it for one switch but , im wondering how to modify my program so that it reads a csv file of multiple switches, like more than one, possibly,hundred.
Hi Priya,
Create a loop and then read the information that you are looking for. Do you already have a script for that?
Can you please provide the script? Thanks.
Thanks for your hard work and for sharing the info. While running the script my csv file is deleting the old data and stored the new data instead of adding rows and storing the next info of the switch. If you include loop details that will be a great help.