RE: Best way to login, run a command, view output, repeat on a

From: Ramcharan, Vijay A (vijay.ramcharan@verizonbusiness.com)
Date: Wed Nov 19 2008 - 20:27:28 ARST


Warning: Long email

Hobbs,

If you are indeed learning Perl, take a stab at learning the Expect
module as it's much more suited to working with network devices.
For review, below is the Expect portion of a Perl script I wrote which
logs in to a bunch of routers, grabs each config, saves it locally,
removes passwords, SNMP strings, TACACS strings etc, then ships them off
via scp to a remote server. Much of that is left out for the sake of
brevity.

Naturally, you'll need to fill in the missing pieces for variables and
such but you should be able to figure out most or all of what's missing
if you are getting into Perl. This is actually the first Perl script
I've ever had the motivation or reason to write as I do any other
scripting (fewer these days) with VBS; being a former Windows admin. I
tried mightily to get Perl Expect to run on Windows, never succeeded so
I had to go do it on a Linux distro.

 ---------------------
my %IPList = (
        "192.168.248.1","ssh",
        "192.168.248.6","telnet",
);

sub DoList {
        print "Getting configs in hash 'IPList'\n";
        
        #Turn on debugging until script testing is completed
        #$Expect::Debug = 1;
        #$Expect::Exp_Internal =1;
        
        foreach (keys %IPList) {
                print "\n\n\n\tNew Host IP: $_, reach via
$IPList{$_}\n\t Please wait...\n";
                sleep 1;
                
                my
($method,$cmd,$pmatch,$tst,$hostnm,$logfile,$data,$ptrn,$repl);
                $method = lc($IPList{$_});
                
                if ($method eq 'telnet') {
                        $cmd = "telnet $_";
                } elsif ($method eq 'ssh') {
                        $cmd = "ssh -o 'StrictHostKeyChecking=no'
$username\@$_";
                } else { print "\nlc($_) does not have a valid reach
method.\nPlease correct and re-run script, doing next!\n",next;}
                        
                #Begin telnet or ssh session
                my $exp = Expect->spawn($cmd) or print "Unable to spawn
$cmd\n\nWith error: $!", die;
                
                #if you want to pass control over to a person
                #$exp->interact;
                #Wait a bit longer on initial connect in the event there
is slowness to respond; like with SSH for example
                $exp->expect(60,"Username:","ssword:","PASSCODE:");
                #$pmatch = $exp->match();
                
                #This block for handling SSH AAA logins
                if ("$method" eq 'ssh' && $exp->match() =~ /ssword:/i)
{
                        print "\n\tI see SSH password prompt for
username $username...";
                        print "\n\t Sending TAC+/AAA password/passcode
via SSH...\n";
                        $exp->send("$tacpwd\n");
                        $exp->expect(5,">","#");
                }
                elsif ($exp->match() =~ /username:/i) {
                        #This block for handling telnet AAA logins
                         #print "\n\tMatched pattern was: $pmatch";
                        print "\n\tSending username $username...\n";
                                
                        $exp->send("$username\n");
                        $exp->expect(5,"ssword:","PASSCODE:");
                                                
                        if ($exp->match() =~ /ssword:|passcode:/i) {
                                print "\n\tSending TAC+/AAA
password/passcode...\n";
                                                
                                $exp->send("$tacpwd\n");
                                $exp->expect(5,">","#");
                        } else {print die("\n\n\tCannot send TAC+/AAA
pwd, response $exp->match()\n\tUnhandled response, please fix!\n");}
                }
                elsif ($exp->match() =~ /ssword:/i) {
                        print "\n\tSending line password...";
                        $exp->send("$linepwd\n");
                        $pmatch=$exp->expect(5,">","#");
                } else {print die("\n\n\tCannot perform login, response
$exp->before()\n\tUnhandled response, please fix!\n");}
                
                #This block for handling ">" prompt
                if ($exp->match() =~ /\>/) {
                        print "\n\tAt user prompt, sending 'en'
string...";
                        $exp->send("enable\n");
                        $exp->expect(5,"ssword:");
                                                        
                        if ($exp->match() =~ /ssword:/i) {
                                print "\n\tSending enable
password/secret...";
                                $exp->send("$enapwd\n");
                                $exp->expect(5,"#");
                        }
                }
                
                #Ready to run commands
                if ($exp->match() =~ /\#/) {
                        print "\n\n\tI am now at the enable
prompt!\n\tReady to run commands\n";
                        
                        $_ = $exp->before();
                        #print "\t String prior to match was: $_";
                        
                        $tst = /(\S+)/;
                        $hostnm = $1;
                        print "\tHostname is $hostnm\n";
                        
                        $logfile =
"$ldir$hostnm-$currdate-$currtime.cfg";
                        print "\tLogfile is: $logfile\n";
                        
                        #Begin host enable commands here
                        #Note that logfile is opened in truncate mode so
that any existing content wiped first
                        $exp->log_file("$logfile","w");
                        $exp->send("show runn\n
");
                        $exp->expect(60,"$hostnm#");
                        
                        #$exp->send("show runn\n");
                        #until ($exp->expect(2,"$hostnm#")) {
                        # $exp->send(" ");
                        #}
                                                
                        #Stop logging, close file
                        $exp->log_file(undef);
                        
                        #Done with host, exit
                        $exp->send("exit\n");
                        $exp->soft_close;
                        
                        #work on logfile data in $logfile, below this
line, remove passwords, get output into desired format etc.

                        
                } else { die $!;}
                        
                } else {print "\n\nDid not see any expected output,
critical error!\nLast match $exp->match()\n\tDoing next host!\n";}
                                                
        }
}

--------------------------------------------
 
Vijay Ramcharan
 
-----Original Message-----
From: nobody@groupstudy.com [mailto:nobody@groupstudy.com] On Behalf Of
Scott Morris
Sent: November 19, 2008 16:34
To: 'Hobbs'; 'Cisco certification'
Subject: RE: Best way to login, run a command, view output, repeat on a
bunch of routers

Kiwi's Cattools is good.. Also, you can do scripting with SecureCRT.

HTH,

Scott Morris, CCIE4 #4713, JNCIE-M #153, JNCIS-ER, CISSP, et al.
CCSI/JNCI-M/JNCI-ER
Senior CCIE Instructor

smorris@internetworkexpert.com

 

Knowledge is power.
Power corrupts.
Study hard and be Eeeeviiiil......
 

-----Original Message-----
From: nobody@groupstudy.com [mailto:nobody@groupstudy.com] On Behalf Of
Hobbs
Sent: Wednesday, November 19, 2008 12:35 PM
To: Cisco certification
Subject: OT: Best way to login, run a command, view output, repeat on a
bunch of routers

Hello,

I am looking for a way to automate the following:

1) Log into a router (hostname taken from a list of router names or IP
addresses)

2) Run the command "show int | inc proto|error"
   (to see the number errors on a all interfaces of a router)

3) Put the output in a file or display it on the terminal

4) Move on to the next router.

I have been looking at the Net::Telnet::Cisco module for Perl but I am
not
too handy with Perl (but I am learning it).
Is there a better way to do it?

thanks

Blogs and organic groups at http://www.ccie.net



This archive was generated by hypermail 2.1.4 : Mon Dec 01 2008 - 08:18:31 ARST