Here's what I'm using for IOS startup capture; it's modeled on the NXOS script.
To get the running config, change $ssh->send( "sh start" ); to $ssh->send( "sh running" );
Change IOS-SSH Capable family to use Scripting
In order to avoid using TFTP, it was desired to allow the IOS-SSH Device family to
use the same scripting as other IOS devices. However, it wasn’t obvious how to
do that as this family didn’t present an option for scripting. Under ticket
21791249-01, we found that you can force the type of communication to be used
for a particular device family. Open the Component Detail, then modify the
attribute NCM_SELECTED_COMM_MODE.
Double click attribute, remove check from No Change, Change from SNMP/TFTP to script
Al
==================================== script ================
#!/opt/SPECTRUM/bin/perl -w
# This script will capture the startup configuration of a
# Cisco IOS device through an SSH session and print it to STDOUT.
# It is based on the standard Spectrum startup configuration script for NXOS.
# Error Codes:
# 0 = Success
# 255 = Usage error
# 254 = Invalid timeout value
# 252 = Login error
# 249 = Exec prompt not found error
# 244 = Error retrieving configuration
# 245 = Insufficient privileges
# 253 = Unexpected output
#
use strict;
use warnings;
use Net::SSH::Expect;
$ENV{'PATH'} = "/usr/bin:". $ENV{'PATH'};
### Main ###
if( $#ARGV != 4 && $#ARGV != 5 )
{
print "Usage: capture_startup.pl <device IP> <user> <pass> <enable_pass>
<login_timeout_in_seconds> <capture_timeout_in_seconds>\n";
print STDERR "Usage: capture_startup.pl <deviceIP> <user> <pass>
<enable_pass> <login_timeout_in_seconds> <capture_timeout_in_seconds>\n";
exit 255;
}
elsif( $ARGV[4] < 1 || $ARGV[4] > 600 )
{
print "$ARGV[4] is the login timeout and must be an int between 1 and 600 seconds\n";
print STDERR "$ARGV[4] is the login timeout and must be an int between 1 and 600 seconds\n";
exit 254;
}
elsif( $#ARGV == 5 && ( $ARGV[5] < 1 || $ARGV[5] > 600 ) )
{
print "$ARGV[5] is the capture timeout and must be an int between 1 and 600 seconds\n";
print STDERR "$ARGV[5] is the capture timeout and must be an int between 1and 600 seconds\n";
exit 254;
}
else
{
my $capture_timeout = $ARGV[4];
if( $ARGV[5] )
{
$capture_timeout = $ARGV[5];
}
my $errorCode = 1;
my @data;
my $errorString = "\nHost $ARGV[0]: \n";
($errorCode, @data) = GetConfig( $ARGV[0], $ARGV[1], $ARGV[2], $ARGV[3],
$ARGV[4], $capture_timeout );
if( $errorCode == 0 )
{
# Success. The startup configuration
# content is in the data variable
foreach ( @data ) { print "$_\n" }; # print the configuration to STDOUT
exit 0;
}
else
{
print STDERR $errorString;
if( $errorCode == 245 )
{
print STDERR join " ", @data, "\nEnsure that the device user has
sufficient privileges to disable paging and view the config\n";
}
else
{
print STDERR join " ", @data, "\n";
}
exit $errorCode;
}
}
exit 0;
sub GetConfig
{
my $deviceIP=shift;
my $user=shift;
my $pass=shift;
my $epass=shift;
my $login_timeout=shift;
my $capture_timeout=shift;
my @config;
my $msg;
my $ssh = Net::SSH::Expect->new ( host => $deviceIP,
user => $user,
password=> $pass,
raw_pty => 1,
no_terminal => 0,
timeout => $login_timeout
);
my $login_output;
eval { $login_output = $ssh->login(); };
if( $@ )
{
$msg = "Login has failed: $@";
return( 252, $msg );
}
# login output should contain the right prompt characters
if( $login_output !~ /\>\s*\z/ )
{
$msg = "Login has failed. Didn't see device prompt as expected.";
$ssh->close();
return( 252, $msg );
}
my $enable=$ssh->exec( "enable");
my $exec_login_output;
if($enable =~ /Password:\s+/i) {
$exec_login_output=$ssh->exec( $epass );
} else {
$msg = "Login has failed. Didn't see enable password prompt as expected.";
$ssh->close();
return( 252, $msg );
}
if( $exec_login_output !~ /\#\s*\z/ ) # Replace '#' is the prompt character here
{
# we don't have the '#' prompt, means we still can't exec commands
$msg = "Exec prompt not found.";
$ssh->close();
return( 249, $msg );
}
# disable paging
# different commands for different devices, if they don't
# work then we will get messages about problems later
# specifically the "No prompt after 'sh run'" error
# errmsg doesn't get set when these error and if we use print
# and getlines to read for errors it causes problems with print "sh run"
# later.
# $ssh->exec( "term pager 0" );
my $paging = $ssh->exec( "term len 0" );
if ( $paging =~ /\s?%\s/ )
{
$msg = "Unable to set terminal size to 0 - Insufficient privileges";
$ssh->close();
return( 245, $msg);
}
$ssh->send( "sh start" );
$ssh->timeout( $capture_timeout );
$ssh->peek(0);
while( my $line = $ssh->read_line() )
{
# get configuration content
if( $line !~
/sh start|Building configuration|Current configuration|^\s*$/ )
{
push @config, $line;
}
}
if( @config <= 0 )
{
$msg = "No data retrieved, the capture timeout may be too low.";
$ssh->close();
return( 244, $msg );
}
if( scalar grep { $_ =~ /^%/ } @config )
{
# Ensure show start actually returned the config and not an error
# message containing '%'
return( 245, @config );
}
return( 0, @config ); # everything was okay, return the captured data
}