Invoke-CiscoCommand.ps1
#requires -Version 2.0 -Modules Posh-SSH <#PSScriptInfo .VERSION 1.3 .GUID cc2eb093-256f-44db-8260-7239f70f013e .AUTHOR Chris Masters .COMPANYNAME Chris Masters .COPYRIGHT (c) 2018 Chris Masters. All rights reserved. .TAGS network cisco ios .LICENSEURI .PROJECTURI https://www.powershellgallery.com/profiles/masters274/ .ICONURI .EXTERNALMODULEDEPENDENCIES Posh-SSH .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES Issue with handing the IPAddress parameter an array has been resolved. It will now iterate thru the list. 1.3 - Accepts an SSH session for connection instead of creds. .PRIVATEDATA #> <# .SYNOPSIS Run commands on your Cisco iOS device. .DESCRIPTION Executes commands on a Cisco device as if you were connected to the terminal via SSH. .PARAMETER IPAddress IP address of the Cisco device you want to execute commands on. This can be a piped list. .PARAMETER Command Commands that will be executed on the target system. One command per line, typed in quotes, or held in a string variable. .PARAMETER Credential Credentials with rights to run defined commands on the target device. .EXAMPLE Invoke-CiscoCommand -IPAddress 192.168.1.1 -Command 'show run' -Credential $myCreds Returns the running-configuration of Cisco device located at 192.168.1.1 .EXAMPLE $ip = '192.168.1.1','192.168.2.1' $ip | Invoke-CiscoCommand -Command 'show run' -Credential $myCreds Returns the running-configuration of Cisco device in the array .EXAMPLE $ip = '192.168.1.1','192.168.2.1' $cmd = @' show version | include uptime sh run int vlan 1 '@ Invoke-CiscoCommand -IPAddress $ip -Command $cmd -Credential $myCreds Returns the running-configuration and uptime of Cisco device in the array .NOTES Requires Posh-SSH and Core to run. .LINK https://www.powershellgallery.com/packages/posh-ssh .INPUTS String text for commands, IPaddress object, and PSCredential. .OUTPUTS Returns the value from commands ran. Using the "Verbose" parameter shows the commands ran, and prompts. #> [CmdletBinding(DefaultParameterSetName = 'session')] Param ( [Parameter(Position = 0, Mandatory = $true, ParameterSetName = 'session', HelpMessage = 'Existing Posh-SSH session ID')] [object] $Session, [Parameter(Mandatory=$true,HelpMessage='Command to be run')] [String[]] $Command, [Parameter(Position = 0,ParameterSetName = 'cred',Mandatory=$true,ValueFromPipeline=$true,HelpMessage='IP address')] [Alias('ComputerName','Name','Switch','Router','Host')] [IPAddress[]] $IPAddress, [Parameter(Mandatory=$true,ParameterSetName = 'cred',HelpMessage='Credentials for managed network object')] [PSCredential] [System.Management.Automation.Credential()] $Credential, [Parameter(ParameterSetName = 'cred')] [Switch] $AcceptKey, # Passes param along to POSH-SSH if needed [Parameter(ParameterSetName = 'cred')] [Switch] $Force # Passes param along to POSH-SSH if needed ) Begin { function Script:Get-SSHShellStream { Param ( $Session ) $sHostname = $session.Session.ConnectionInfo.Host $sUsername = $Session.Session.ConnectionInfo.Username $ErrorActionPreference = 'SilentlyContinue' $allStreams = Get-Variable | Where-Object { $_.value -match 'Renci\.SshNet\.ShellStream'} foreach ($tmpStream in $allStreams) { Invoke-Expression -Command ('$tmpObj = ${0}' -f $tmpStream.Name) if ($tmpObj.Session.ConnectionInfo.Username -eq $sUsername -and $tmpObj.Session.ConnectionInfo.Host -eq $sHostname) { return $tmpObj } Remove-Variable -Name tmpObj } } } Process { # Variables $strNewLine = "`n" $strPattern = '#|^$|configuration...|Current configuration :|^\r\n|^$' If (! $Session) { $SshSesssionParams = @{ ComputerName = $IPAddress Credential = $Credential AcceptKey = $true ConnectionTimeout = 90 ErrorAction = 'Stop' } If ($Force) { $SshSesssionParams += @{Force = $Force} } If ($Force) { $SshSesssionParams += @{AcceptKey = $AcceptKey} } $objSessionCisco = New-SSHSession @SshSesssionParams } else { $objSessionCisco = $Session } Foreach ($node in $objSessionCisco) { $SshStream = Get-SSHShellStream -Session $node if (! $SshStream) { $SshStream = New-SSHShellStream -SSHSession $node Invoke-DebugIt -Color green -Message 'CHECK THIS OUT' -Value 'Stream does not exist' -Force -Console } # Set terminal length $SshStream.WriteLine('terminal length 0') $null = $SshStream.Read() $arrayCommands = $Command.Split($strNewLine) Foreach ($strCiscoCommand in $arrayCommands) { $SshStream.WriteLine(('{0}' -f $strCiscoCommand)) # Takes a bit for the command to run sometimes Start-Sleep -Milliseconds 200 } $rawOutput = @() $boolDataReceived = $false :waiter While ($true) { $streamOut = $sshStream.Read() If ($boolDataReceived -eq $true -and $streamOut.Length -eq 0 -and -not $(($rawOutput.Split($strNewLine) | Select-Object -Last 1) -eq '')) { break waiter } If ($streamOut.Length -gt 0) { $rawOutput += $streamOut $streamOut = $null $boolDataReceived = $true # Watch until we do not receive data anymore } Start-Sleep -Milliseconds 200 } If (!($PSBoundParameters['Verbose'])) { $rawOutput = $rawOutput.Split($strNewLine) | Select-String -NotMatch -Pattern $strPattern } $rawOutput Remove-Variable -Name SshStream } if (! $Session) { $null = Remove-SSHSession -SessionId $($objSessionCisco.SessionId) } } |