2

I have a script that will ssh to a list of routers and run commands from commands.txt. I want to enable after I connect to the router through ssh before I execute the rest of my commands in commands.txt I have two questions. First, how do I pass the enable command? It doesnt seem to be doing anything when I put it as my first line in commands.txt.Second, Once I figure out the enable prompt part, how would I pass my credentials for the script to be fully automatic?

Script

enter image description here

Commands.txt

enter image description here

When I run this current script I enter my password when it prompts me for connection to the router. Then it just displays % Type "show ?" for a list of subcommands and then goes on and connects to the next router and asks for my credentials.

3 Answers 3

3

Consider looking at RANCID. It's primarily intended as a configuration backup tool for Cisco and other networking devices, but one of its components, clogin, is essentially an Expect script that does exactly what you're asking. Using the command and router file listings in your example, you could execute the commands on all routers like this:

clogin -u user -p pass -e enablepass -x commands.txt $(cat routers.txt)

It can read a configuration file in which you can store login names and passwords, so you can avoid passing them on the command line. It has multiple login options, so it can deal with cases where you aren't using aaa new-model and just have passwords on the VTYs, and cases with older gear that asks for the username in response to the enable command.

The only real downside is that it's not especially quiet. For instance, if you want the output of show version, you'll get that, but you'll also get all the login banners, login/passwords prompts, and command prompts in your output.

2

I have been using this perl script for about a year now. it's an evolution of several snippets of perl scripts i have found on various forums plus a bit of trial and error but it works well. You will need to install the module Time::HiRes for the usleep, but i found that it helps with execution of commands on remote switches and routers where the response time to a command is a little longer. It will skip over devices that do not respond or fail authentication and carry on with the next device in the list, and provides a log file for each device named with it's ip address.

Hope it's helpful to someone.

#
# usage: perl cisco.pl (target_hostfile) (ssl_password) (enable_password)
#
use Net::SSH2;
use warnings;
use strict;
use Time::HiRes qw(usleep);
use File::Slurp;
print "\nEnter switch list filenane: ";
my $input = <STDIN>;                        ### target hosts file from STDIN
chomp($input);
my @hostfile = read_file($input,chomp => 1);        ### read target host file
my $arrSize = @hostfile;
my $user = "username"; ### your username
print "\nEnter ssh password: ";
my $password = <STDIN>;        ### ssh password from STDIN
chomp($password);
print "\nEnter enable password: ";
my $secret = <STDIN>;        ### enable password from STDIN
chomp($secret);
print "\nEnter command delay in miliseconds: ";
my $delay = <STDIN>;
chomp($delay);
my $delaytime = $delay/1000;
print "\nCopmmand delay confirmed: $delaytime Seconds\n";
print "\nEnter command list filename: ";
my $commandlist = <STDIN>;
chomp($commandlist);
my @commandfile = read_file($commandlist,chomp => 1);
my $commandsize = @commandfile;
my $i = 0;
my $j = 0;
$delay*=1000;  ### convert delay into microseconds for usleep command
for ($i = 0; $i < $arrSize; $i++){
my $ssh = Net::SSH2->new();
if(!$ssh->connect($hostfile[$i])){
        print("Connection Failed ($hostfile[$i]\n");
     next;
}
usleep($delay);  ### time in microsecond
if(!$ssh->auth_password($user,$password)){
        print("Authentication Failed ($hostfile[$i]\n");
        next;
}
usleep($delay);  ### time in microsecond
my $channel = $ssh->channel();
$channel->blocking(0);
$channel->shell();
print $channel "enable\n";
usleep($delay);  ### time in microsecond
print $channel "$secret\n";     ### enable password from input string3
usleep($delay);  ### time in microsecond
print $channel "term len 0\n";
usleep($delay);  ### time in microsecond
for ($j = 0; $j < $commandsize; $j++){
print $channel "$commandfile[$j]\n";
    usleep($delay);  ### time in microsecond so 1 millisecond == 1000 microseconds
}
open (my $OUTPUTFILE, ">$hostfile[$i].log") or die "Can't open $hostfile[$i].log: $!";   ### target host as filename
while (<$channel>) {
chomp;
print $OUTPUTFILE "$_";
}  

close $OUTPUTFILE or die "$OUTPUTFILE: $!";
}
close $OUTPUTFILE or die "$OUTPUTFILE: $!";
}
1

I would look at using something like expect instead of just trying to redirect from a file. expect will handle password prompts and the like, and respond with the information you want, based on the output.

http://expect.sourceforge.net/

Under rhel6 the package would be called expect. There is also a python module that does sort of the same thing called pexpect, available from the rhel6 updates repo. A perl module that does the same is called perl-Expect.

This would probably give you better results.

This pages http://nixcraft.com/showthread.php/15060-script-to-auto-login-to-cisco-router-(-telnet-and-SSH) gives some examples of what you are trying to do.

edit: Just found another link from cisco describing this also:

https://supportforums.cisco.com/discussion/11553001/script-automate-tasks

1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .