Using powershell to backup SSH devices (And more!)

I’ve recently been moving to a new RMM product that offers better automation policies than the one I’ve used before. The new RMM product also has the ability to run scripts with in and output from the RMM product itself – e.g. if a network contains a Juniper router, You can run automation policies based on the devices in that network.

Of course this opens up great opportunities for automation of device based backups, like routers, switches, etc. I’ve created a powershell script to automate this. The script currently supports Draytek, Juniper SRX series, Juniper SSG series, and Sonicwall devices :). The script is pretty much self explanatory due to the comments.

#######################################
#script created by TeGek – http://www.cyberdrain.com
#Router / Juniper SRX backup script version 0.1
#Runs a backup of the juniper config, drops the file in C:\RouterBackups and uploads this file to a remote FTP site.
#Parameters: RouterIP, DeviceType, Username, Password
#######################################
Param(
[string]$RouterIP,
[string]$DeviceType,
[string]$Username,
[string]$Password
)
#######################################
#set variables and create a secure string for username/password of the router.
$date = Get-Date -format (“dd-M-yyyy”) #We get the date in the European format.
$clientID = $env:USERDNSDOMAIN #we’ll use the userDNSdomain to define the clien tname, it assists in FTP uploads and to clarify who this config file belongs to.
$secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ($username, $secpasswd)
$FTPSERVER = “1.1.1.1”
#######################################
#Set the correct command, we do this based on the device. You can simply add an item based by copy+pasting the statement and entering the correct SSH command. A case select probably would have been nicer here, But this statement is quicker to copy.
if($DeviceType = “Juniperssg”){ $command = “get config”}
if($DeviceType = “Junipersrx”){ $command = “cli show config”}
if($DeviceType = “draytek”){ $command = “sys config”}
if($DeviceType = “sonicwall”){ $command = “export current-config cli”}
#######################################
#Next, we try to create a new directory on C:\ to store the temporary files, You can also choose to keep this folder intact for local router backups 🙂
try{
New-Item -Path C:\RouterBackups -ItemType Directory -force
}catch{
write-host “Router Backups Directory exists, Moving on”
}
#######################################
#We download darkoperator/Carlos Perez’s SSH client. For more information goto: http://www.darkoperator.com/.
Try{
iex (New-Object Net.WebClient).DownloadString(“https://gist.github.com/darkoperator/6152630/raw/c67de4f7cd780ba367cccbc2593f38d18ce6df89/instposhsshdev”)
Import-Module “$env:homepath\documents\windowspowershell\modules\posh-ssh”
} catch {
write-host “Download SSH client failed! Backup Failed”
}
#######################################
#after downloading, we run a simple command that states we’d like to run the backup. Of course this depends on the type of device.
try{
New-SSHSession -ComputerName $RouterIP -Credential $mycreds
Invoke-SSHCommand -Index 0 -Command $command out-file C:\RouterBackups\$clientid-$date.txt
Get-SSHSession | Remove-SSHSession
}catch{
write-host “Could not connect to SSH, Backup Failed”
}
#######################################
#And here we try to upload the file – If its not required just delete this section 🙂
Try{
$file = “C:\RouterBackups\$clientid-$date.txt”
$ftp = “ftp://$FTPSERVER/$clientID-$date.txt”
“ftp url: $ftp”
$webclient = New-Object System.Net.WebClient
$uri = New-Object System.Uri($ftp)
“Uploading $File…”
$webclient.UploadFile($Uri, $File)
}catch{
write-host “Uploading file to FTP Failed!”
}

5 Comments

  1. Perry February 9, 2016 at 8:36 pm

    I really want this to work! I kept getting “Could not connect to SSH, Backup Failed”…. so I stepped through the processes and I’m getting hung on the Invoke-SSHComman. Any help would be appreciated! The following is the error:
    Invoke-SSHCommand : Cannot process argument transformation on parameter ‘TimeOut’. Cannot convert value “out-file” to type “System.Int32”. Error: “Input string was not
    in a correct format.”
    At line:2 char:47
    + Invoke-SSHCommand -Index 0 -Command $command out-file C:\RouterBacku …
    + ~~~~~~~~
    + CategoryInfo : InvalidData: (:) [Invoke-SSHCommand], ParameterBindingArgumentTransformationException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,Invoke-SSHCommand

    1. TeGek February 18, 2016 at 8:27 pm

      Hi Perry,

      Thanks for noticing! I see wordpress autocorrection has caused this.

      to fix, Replace:
      Invoke-SSHCommand -Index 0 -Command $command out-file C:\RouterBackups\$clientid-$date.txt

      With:
      Invoke-SSHCommand -Index 0 -Command $command | out-file C:\RouterBackups\$clientid-$date.txt

  2. shehzad February 10, 2017 at 2:52 am

    A wonderfully written script and i can see it has all the String variables present but fails to invoke SSH commands. below is the error i get
    As you can see credentials are correct and I can establish a connection but the next command fails.

    PS C:\Users\Administrator> New-SSHSession -ComputerName $RouterIP -Credential $mycreds

    SessionId Host Connected
    ——— —- ———
    1 192.168.10.254 True

    PS C:\Users\Administrator> Invoke-SSHCommand -index 1 -command $command |out-file C:\RouterBackups\$clientid-$date.txt
    Exception calling “BeginExecute” with “0” argument(s): “An established connection was aborted by the server.”
    At C:\Users\Administrator\Documents\WindowsPowerShell\Modules\posh-ssh\Posh-SSH.psm1:348 char:17
    + $Async = $cmd.BeginExecute()
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SshConnectionException

    1. TeGek February 10, 2017 at 12:44 pm

      Hi Shezad,

      I haven’t looked at this script in some time, but some things you could try;

      Replace :
      Invoke-SSHCommand -index 1 -command $command |out-file C:\RouterBackups\$clientid-$date.txt

      With :

      Invoke-SSHCommand -index 0 -command $($command) |out-file C:\RouterBackups\$clientid-$date.txt

  3. jammy April 3, 2017 at 7:07 am

    thanks for the source dude, gonna help me get my backup script written

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.