cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
4007
Views
10
Helpful
11
Replies

Assistance with Python Script

cscecela7
Level 1
Level 1

Hello all! I need to push out a new configuration to about 2000+ Cisco IOS devices and about 1000+ Fortinet firewall appliances. I found a nice script that does most of what I want but won't execute configuration commands. For some reason if I alter the configuration it won't accept the configuration commands. Since I have a huge IP listing I will need to call the IP addresses from a file and to be able to log the results of the output to a file.

Below is the script I found on the internet that works great for issuing show commands:


from __future__ import print_function
from netmiko import ConnectHandler
import sys
import time
import select
import paramiko
import re
fd = open(r'C:\Command_Output.txt','w') # Where you want the file to save to.
old_stdout = sys.stdout
sys.stdout = fd
platform = 'cisco_ios'
username = 'admin' # edit to reflect
password = 'XXXXX' # edit to reflect

ip_add_file = open(r'C:\IPAddressList.txt','r') # a simple list of IP addresses you want to connect to each one on a new line

for host in ip_add_file:
host = host.strip()
device = ConnectHandler(device_type=platform, ip=host, username=username, password=password)
output = device.send_command('terminal length 0')
# output = device.send_command('enable') #Editable to be what ever is needed - Uncomment by removing the # at the begining of the line
print('##############################################################\n')
print('...................CISCO COMMAND SHOW RUN OUTPUT......................\n')
output = device.send_command('sh run')
print(output)
print('##############################################################\n')
print('...................CISCO COMMAND SHOW IP INT BR OUTPUT......................\n')
output = device.send_command('sh ip int br')
print(output)
print('##############################################################\n')

fd.close()

If I try to alter the commands such as output = device.send_command('configure terminal') then I want to be able to execute more commands line by line.

Below is another script that does what I want but doesn't call IP's from a file nor writes the output to a file.


import paramiko
import time

ip_address = "10.164.178.254"
username = "admin"
password = "XXXXX"

ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_client.connect(hostname=ip_address,username=username,password=password)

print ("Successful connection", ip_address)

remote_connection = ssh_client.invoke_shell()

remote_connection.send("configure terminal\n")
remote_connection.send("snmp-server community ORION\n")
remote_connection.send("snmp-server host 10.1.4.82 version 2c ORION\n")
remote_connection.send("line vty 0 4\n")
remote_connection.send("exec-timeout 60\n")

remote_connection.send("end\n")

time.sleep(1)
output = remote_connection.recv(65535)
print(output)

ssh_client.close

11 Replies 11

jmperlewitz
Level 1
Level 1

I am more familiar with Paramiko, so I will help you with that script.  It is easy to open files to read from and to write to.  Thy the following:

 

import paramiko
import time

username = "admin"
password = "XXXXX"

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

# Connect to each IP in your file
with open("{{ Your_File_Location",'r') as ip_file:
    for ip_address in ip_file:
          ssh_client.connect(hostname=ip_address,username=username,password=password)

          print ("Successful connection", ip_address)
          remote_connection = ssh_client.invoke_shell()
          remote_connection.send("configure terminal\n")
          remote_connection.send("snmp-server community ORION\n")
          remote_connection.send("snmp-server host 10.1.4.82 version 2c ORION\n")
          remote_connection.send("line vty 0 4\n")
          remote_connection.send("exec-timeout 60\n")
          remote_connection.send("end\n")
          time.sleep(1)
          output = remote_connection.recv(65535)          
          print(output)
          # Write to file
          # Make sure file already exists, you will append to it 
          with open("{{Your_File_Location}},'a' as write_output:
               write_output.write(output)
               write_output.write("\n\n")
          ssh_client.close

Did it work?  If so, please don't forget to mark the post as helpful.  If not, what do you still need help with?

Im struggling to get this to work. Whats the formatting of the IP list file? 

It stops at "ssh_client.connect(hostname=ip_address,username=username,password=password)" 

Im getting "socket.gaierror: [Errno 11001] getaddrinfo failed" 

Right now i use a simple txt file with IPs on each line 

Hello,

 

which of the three scripts in this post are you using ?

Hi :)

I'm using the last one with paramiko. Have python 3.8 and paramiko
installed.

I'm thinking the format of my IP list may not be correct.

Hello,

 

I looked around, and found a post where somebody suggests to strip the 'newline' at the end of your lines in your text file:

 

import paramiko
import time

username = "admin"
password = "XXXXX"

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

# Connect to each IP in your file
--> with open("{{ Your_File_Location",'r')[:-1] as ip_file:
for ip_address in ip_file:
ssh_client.connect(hostname=ip_address,username=username,password=password)

print ("Successful connection", ip_address)
remote_connection = ssh_client.invoke_shell()
remote_connection.send("configure terminal\n")
remote_connection.send("snmp-server community ORION\n")
remote_connection.send("snmp-server host 10.1.4.82 version 2c ORION\n")
remote_connection.send("line vty 0 4\n")
remote_connection.send("exec-timeout 60\n")
remote_connection.send("end\n")
time.sleep(1)
output = remote_connection.recv(65535)
print(output)
# Write to file
# Make sure file already exists, you will append to it
with open("{{Your_File_Location}},'a' as write_output:
write_output.write(output)
write_output.write("\n\n")
ssh_client.close

Does not seem to work. This is the exact im trying to run right now: 

 

from __future__ import print_function
from netmiko import ConnectHandler
import sys
import time
import select
import paramiko
import re
import ip_address

username = "xxxxxxx"
password = "xxxxxxxxx"

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

# Connect to each IP in your file
with open("ip_list",'r') as ip_file:
    for ip_address in ip_file:
          ssh_client.connect(hostname=ip_address,username=username,password=password)

          print ("Successful connection", ip_address)
          remote_connection = ssh_client.invoke_shell()
          remote_connection.send("configure terminal\n")
          remote_connection.send("exit\n")
          remote_connection.send("configure terminal\n")
          remote_connection.send("exit\n")

          time.sleep(1)
          output = remote_connection.recv(65535)          
          print(output)
          # Write to file
          # Make sure file already exists, you will append to it 
          ssh_client.close

I am getting the following error:

C:\Users\xxxxxx\Documents\Scripting\multihost ssh>test3.py
Traceback (most recent call last):
  File "C:\Users\xxxxxx\Documents\Scripting\multihost ssh\test3.py", line 19, in <module>
    ssh_client.connect(hostname=ip_address,username=username,password=password)
  File "C:\Users\xxxxxx\Python38-32\lib\site-packages\paramiko\client.py", line 340, in connect
    to_try = list(self._families_and_addresses(hostname, port))
  File "C:\Users\xxxxxx\Python38-32\lib\site-packages\paramiko\client.py", line 203, in _families_and_addresses
    addrinfos = socket.getaddrinfo(
  File "C:\Users\xxxxxx\Python38-32\lib\socket.py", line 918, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno 11001] getaddrinfo failed


Alternatively I would love to adjust this script to use with a IP list text file, but so far ive failed: 

from netmiko import ConnectHandler,redispatch

R1 = { 
   'device_type': 'cisco_ios', 
   'host': 'xxxxxx', 
   'username': 'xxxxxx', 
   'password': 'xxxxxx', 
   } 
R2 = { 
   'device_type': 'cisco_ios', 
   'host': 'xxxxxx', 
   'username': 'xxxxxx', 
   'password': 'xxxxxx', 
   } 
routers = [R1,R2]
for routerslist in routers :
 net_connect = ConnectHandler(**routerslist)
 config_commands = ['exit','show ip interface brief | i loopback']
 output = net_connect.send_config_set(config_commands)
 print (output)

The following script works perfectly, but it doesn't print the commands, it will only print output from show commands. So for configuration its not so practical. 

from __future__ import print_function
from netmiko import ConnectHandler

import sys
import time
import select
import paramiko
import re
platform = 'cisco_ios'
username = 'xxxxxx'
password = 'xxxxxxxx'

ip_add_file = open('ips.txt','r') 

for host in ip_add_file:
    try:
        device = ConnectHandler(device_type=platform, ip=host, username=username, password=password)
        output = device.send_command('show run | i hostna')
        print(output)

        output = device.send_command('show running-config | include ip http server|secure-server')
        print(output)
    except Exception:
        print("Unable to connect")

 

What do you mean by "it doesn't print the commands" ? 

 

I thought you wanted to send configuration commands to the device so why are you bothered about printing that out ?

 

Jon

I guess i just want some sort of confirmation it was executed 

 

Ok so just - 

 

output  = device.send_config_set(cmds) 

 

and then you can print the output if that is what you want. 

 

Jon

awesome, so simple. This is exactly what I wanted :) 

This does exactly what I wanted: 

from __future__ import print_function
from netmiko import ConnectHandler

import sys
import time
import select
import paramiko
import re
platform = 'cisco_ios'
username = 'xxxxxx'
password = 'xxxxxxx'

ip_add_file = open('ips.txt','r') 

for host in ip_add_file:
    try:
        device = ConnectHandler(device_type=platform, ip=host, username=username, password=password)
        output = device.send_config_set([cmd1','cmd2'])
        print(output)

    except Exception:
        print("Unable to connect")
Review Cisco Networking for a $25 gift card