Here is a script I use to back up all of our Cisco routers and switches (about 75) of them that takes about 20 seconds to complete. The reason it’s so fast is that it supports multithreading (the ability to connect to multiple devices simultaneously). The script uses a file called devices with a list of IP addresses (1 per line) that you want to connect to and perform backups from. This script supports SSH v1 and v2 since I needed something more secure than telnet to do the backups. The script will name the files with the IP address, date and time and put them in directories with the ip address, so that it will not overwrite previous configs. As you can see, it also requires a couple of modules to work…

#!/usr/bin/perl -w
##################################################################################
# Router Backup script -- Supports SSH v1, v2 and multithreading (for speed).  This script uses the file
# devices for all of the routers and switches that need backups, it also cleans up the backups by
# removing the ^M's and the commands issued (show run, term length 0 etc.)                -LB 4-22-2008
##################################################################################
#Modules used
use Expect;
use strict;
use POSIX;
use Proc::Queue size => 10, debug => 1;
use POSIX ":sys_wait_h";

#Variables used
$| = 1;
my $nc = 1;
my $username = "username";
my $password = "password";
my $filename;
my $filepath;
my $backupdir = "/configs/";
my $timeout = 10;
my @logfile;
my $line;
my $host;
my $hosts;
my @hosts;

#Main script
open DEVICES, "devices";
while ()  {
if (/^#/)   {
     next;
     }
elsif (/^\d+/)   {
     ($host) = /(^\d+\.\d+\.\d+\.\d+)/;
     }
else {next;}
push @hosts, "$host";
}
close DEVICES;

for my $c (1..$nc)   {
        #child process

foreach $host (@hosts)   {
        defined (my $pid = fork) or die "Couldn't fork: $!";
next if $pid;

$filename = strftime("$host-%m-%d-%Y.%H.%M.txt", localtime);
my $filepath = "$backupdir$host/$filename";
mkdir "$backupdir$host";

my $command = Expect->spawn("ssh $username\@$host");
$command->expect($timeout, -re => "password:") or die("Failed to get password prompt");
print $command "$password\r";
sleep 1;
print $command "terminal length 0\r";
$command->log_file("$filepath");
print $command "sho run\r";
my $redo = 1;
while($redo)   {
    $command->clear_accum();
    $command->expect(1,
               [ qr/More/ => sub { my $command = shift; print $command "\r"; exp_continue; } ],
               [ qr/#/ => sub { my $exp = shift; $redo = 0; exp_continue; }],);
}
print $command "exit\r";
$command->soft_close();
$command->log_file(undef);
@ARGV = ("$filepath");
$^I = ".bak";
while (<>)  {
        s/^Logoff//||s/^Connection to.*//||s/\S+#exit//||s/\S+#terminal length 0//||s/\S+#sho run//||s/Building configuration...//;
             s/\cM//g;
        print;
}
unlink "$filepath.bak";
$host = "";
$filename = "";
exit;
}
1 while waitpid(-1, WNOHANG)>0; # reaps childs          #1 while wait() > 0;
}