cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
450
Views
1
Helpful
4
Replies

Need Help with Python code

Viper2000
Level 1
Level 1

Good day everyone.

My name is Johannes Robbetze and I am new to the automation side of things. I try to write a Python script that will log in to multiple Cisco switches and change the local username and password as well as the enable secret password. When I run the script I get the below output and it does not change the config. Could I please ask for some help in pointing me in the correct direction to fix the code.

Viper2000_0-1747629970213.png

SSHSCRIP.py

import paramiko
import time
import getpass
import os
from host_file import device_list
from config_file import host_commands

UN = input("Username : ")
PW = getpass.getpass("Password : ")
SE = getpass.getpass("Secret : ")

# For loop allows you to specify number of hosts
for ip in device_list:
    print (ip)
    twrssh = paramiko.SSHClient()
    twrssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    twrssh.connect(ip, port=22, username=UN, password=PW)
    remote = twrssh.invoke_shell()
    remote.send('term len 0')
    remote.send('enable')
    remote.send('%s' %SE)
    time.sleep(1)
    #This for loop allows you to specify number of commands  you want to enter
    #Dependent on the output of the commands you may want to tweak sleep time.
    for commands in host_commands:
        remote.send( commands)
        time.sleep(2)
        buf = remote.recv(65000)
        print (buf)
        f = open('sshlogfile0001.txt', 'a')
        #f.write(buf)
        f.close()
    twrssh.close()
 
HOSTS_FILE.py
device_list = []
f = open(r'C:\Users\JohannesR\Downloads\host_file.txt', 'r')
for line in f:
    device_list.append(line.strip())
f.close()
print
device_list
 
Config_File.py
host_commands = []
f = open(r'C:\Users\JohannesR\Downloads\config_file.txt', 'r')
for line in f:
    host_commands.append(line.strip())
f.close()
print
host_commands

 

4 Replies 4

Jesus Illescas
Cisco Employee
Cisco Employee

From your script I'm not sure why is not working. I would assume the commands you have on config_file.txt works, however assuming is not good.

So my advice is:

  • First make sure this works manually.
  • Then try to run your script with only one device and one command.
  • Remove the loops so you remove complexity that is not required at this point.
  • Print the command you are actually sending before remote.send( commands) so you are sure what you are sending.

Another piece of advice is to use context managers (with) rather than opening and closing files, this makes the code easier to read and you will be sure your close your reading.

Hi,

It looks like you're just sending the text without a newline/enter.

I haven't worked with paramiko, but other examples I've found included a newline character in the .send command.

So instead of "remote.send('term len 0')" you should probably be doing "remote.send('term len 0\n')"
(Adding the " \n " at the end)

That being said, there are two other observations I would like to point out:

#1
While I'm not that familiar with paramiko, in the past I've been using netmiko, which is very useful for this sort of thing, as it handles some of the basics so you don't need to send individual commands such as the term length and enable.
I've found it easy to use if I'm using python to do any mass-changes.

#2
I'm not sure if the output you posted is from a LAB environment or not, but your password you use can be seen in the screenshot.
If by any chance this is something you use you should now consider the password to be compromised.

Hi Jonathan

Thank you. The password that you see is just a test and not the real password that will be used. Let me check with the suggested changes if I can get it to work. Thank you 

Thank you to everyone who gave some input. I have changed the script and now it is working as expected.

from netmiko import ConnectHandler
import getpass

# Read IP addresses from a file
with open(r'C:\Users\JohannesR\Downloads\host_file.txt', 'r') as file:
    ip_addresses = file.read().splitlines()

# Prompt for SSH credentials
username = input('Enter your SSH username: ')
password = getpass.getpass('Enter your SSH password: ')
secret = getpass.getpass('Enter your Enable password: ')

# Define the command set to be executed on each switch
with open(r'C:\Users\JohannesR\Downloads\config_file.txt', 'r') as file:
    commands_list = file.read().splitlines()

# Loop through each IP address and configure the switch
for ip in ip_addresses:
    device = {
        'device_type': 'cisco_ios',
        'ip': ip,
        'username': username,
        'password': password,
        'secret': secret,
        "read_timeout_override": 90,
        }
    try:
        net_connect = ConnectHandler(**device)
        net_connect.enable()
        output = net_connect.send_config_set(commands_list, read_timeout=0)
        print(output)
        net_connect.disconnect()
    except Exception as e:
        print(f"Failed to configure switch {ip}: {e}")