Last active
January 3, 2018 18:11
-
-
Save tylerapplebaum/2d95c62872eaf10d07d0f930b9edaaf0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.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
Hey, thanks! I really like that.