Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bevinduplessis/d79d0fd734d59e4693eb757d19ecdc6a to your computer and use it in GitHub Desktop.
Save bevinduplessis/d79d0fd734d59e4693eb757d19ecdc6a to your computer and use it in GitHub Desktop.
<#
.SYNOPSIS
Backup-CiscoConfig.ps1 SSHs to a Cisco device and backs up the running configuration to a TFTP server.. Utilizes the Posh-SSH module.
.DESCRIPTION
This script is not possible without darkoperator's Posh-SSH module. Thanks!
To do: Parameterize the device list. 10/05/16
Grab the output of long commands by setting the terminal length to 0 to disable pagination. "term len 0"
Log commands entered on the Cisco device to ensure they're running:
archive
log config
logging enable 100
notify syslog
hidekeys
.NOTES
File Name : Backup-CiscoConfig.ps1
Author : Tyler Applebaum
Requires : PowerShell v3
Last Edited : 10/05/2016
Version : 0.1
.LINK
https://gist.github.com/tylerapplebaum/
.EXAMPLE
C:\PS> .\Backup-CiscoConfig.ps1 -u username -en l3tm3in
.PARAMETER username
Specify the username to use to connect to the network devices
.PARAMETER EnablePW
Specify the enable password of the device
#>
#Requires -version 3.0
[CmdletBinding()]
param(
[Parameter(mandatory=$true, HelpMessage="Specify the username to SSH to the device")]
[Alias("u")]
[string]$Username,
[Parameter(mandatory=$false, HelpMessage="Specify the enable password")]
[Alias("en")]
[string]$EnablePW
)
$TFTPServer = "192.168.190.66" #Change this to your server
$FileDate = get-date -format MMMMddyyyy
Function script:Dependencies {
If ($(Get-Module -ListAvailable | ? Name -like "Posh-SSH") -eq $null) {
iex (New-Object Net.WebClient).DownloadString("https://gist.github.com/darkoperator/6152630/raw/c67de4f7cd780ba367cccbc2593f38d18ce6df89/instposhsshdev")
}
}#End Dependencies
Function script:Credentials {
$SSH_Username = $Username
$SSH_CredFolder = "C:\PS\"
$SSH_CredPath = $SSH_CredFolder + $Username + "_CiscoSSH_TACACS.pwd"
#Check if the C:\PS folder exists. If not, create it.
If ((Test-Path -Path $SSH_CredFolder) -eq $False) {
New-Item -ItemType Directory -Path C:\PS | Out-Null
}
#If the password file does not exist, create it
If ((Test-Path -Path $SSH_CredPath) -eq $False) {
(Get-Credential).Password | ConvertFrom-SecureString | Out-File $SSH_CredPath
}
#Read the password
$SSH_Password = Get-Content $SSH_CredPath | ConvertTo-SecureString
#Create the PSCredential Object
$SSH_Cred = New-Object -Typename System.Management.Automation.PSCredential -ArgumentList $SSH_Username, $SSH_Password
}#End Credentials
Function script:CheckConnection {
$script:Devices = @()
$script:DeviceRange = @("10.160.24.1") #Needs to be parameterized. #REPLACE THESE IPs WITH THE DEVICES TO CONNECT TO
Foreach ($DeviceIP in $DeviceRange) {
Write-Debug $DeviceIP
If (Test-Connection -count 1 -computername $DeviceIP -quiet){
$Devices += $DeviceIP
}
}
}#End CheckConnection
Function script:Connect {
$Session = New-SSHSession -ComputerName $Device -Credential $SSH_Cred -AcceptKey $True
$Stream = $Session.Session.CreateShellStream("dumb", 0, 0, 0, 0, 1000)
}#End Connect
Function script:Disconnect {
#$Stream.Write("logout`n") #Using this leaves the socket in a CLOSE_WAIT state. PowerShell sends FIN, and receives ACK. The socket remains until the PowerShell process is ended. There is apparently a maximum of 63 CLOSE_WAIT sockets per process. PowerShell will hang and do nothing once it reaches this point.
Remove-SSHSession -Index 0 | Out-Null #Using this leaves the socket in a TIME_WAIT state, which times out after 60 seconds. PowerShell sends a FIN, and never receives an ACK. Pipes to null, because it returns a boolean.
}#End Disconnect
Function script:Get-RTRInfo { #Absolutely must set sleep between commands to allow them time to execute. If you have a slow connection, slow router, or a massive show command, you will need to adjust the sleep time.
sleep 2
$FirstPrompt = $Stream.Read().Trim()
Write-Debug $FirstPrompt #Ensure there's no whitespace
If ($FirstPrompt -like "*>*")
{
If ($EnablePW -like $null) {
Write-Host "Enable prompt encountered, no enable PW specified. Please use -en parameter"
exit
} #Make sure we have the enable PW before trying to enter it.
$Stream.Write("en`n")
sleep 1
$Stream.Write("$EnablePW`n")
sleep 1
} #Conquer enable mode
sleep 1
$RTRName = $FirstPrompt.Replace('>','').Replace('#','').Trim()
Write-Debug $RTRName
}#End Get-RTRInfo
Function script:Run-Commands2 {
$Stream.Write("copy run tftp://$TFTPServer/$RTRName$FileDate.txt`n")
sleep 1
$Stream.Write("`n")
sleep 1
$Stream.Write("`n")
sleep 3
While ($Stream.Read() -notlike "*copied*") {
If ($Stream.Read() -like "*copied*") {Break}
}
}#End Run-Commands
. Dependencies
. Credentials
. CheckConnection
Foreach ($script:Device in $Devices) {
$i++
Write-Progress -Activity "Gathering Network Device Data" -Status "Connected to $Device - $i of $($Devices.Count)" -PercentComplete ($i / $Devices.Count*100)
. Connect
. Get-RTRInfo
. Run-Commands2
. Disconnect
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment