Backup Network Configuration with PowerShell

Posted: October 9, 2013 in Powershell
Tags: , , , ,

So, one of the consultants in the company I work at came to me with a strange request.

The request from the customer he was helping was the following. They wanted a way to connect to all the switches within their environment and then run some commands against the switch after connecting to the switch on port 23. Once the connection has been made, then some commands are run to get the current running configuration. Then export this to a text file.

So I found a basic script here. I have since taken this and modified and extended the script. I have added an array for the IPs to be checked. I have also added some checking prior to running any commands. I have added some testing.

First, we test the connection and see if the device is responding to pings. If the device is responding to pings, then test and see if the device is configured for telnet. So basically I am looking to see if port 23 is open. If port 23 is not opened, a log file is updated with the IP Address. If the device is not responding to pings, a log file is updated stating the IP of the “non-responding” device.

As an addition to the script, the files are then added to an e-mail which is sent to whomever you want to add. As part of the email process, a check is done and if an error is thrown, there is more information presented in the console to point you in the correct direction.


## PowerShell: Script To Telnet To Remote Hosts And Run Commands Against Them With Output To A File ##
## Overview: Useful for Telnet connections to Cisco Switches and other devices. Can add additional command strings
## Usage Examples: Add your environment specific details into the parameters below, or include when calling the script:
## ./PowerShellTelnetRemoteSession.ps1 "127.0.0.1" "23" "admin" "password" "term len 0" "en" "enablepassword" "show interface"
 
param(
    #[string] $remoteHost = "172.31.0.111", 
    #[int] $port = 23,
    [string] $username = "admin",
    [string] $password = "",
    #[string] $termlength = "term len 0", #Useful for older consoles that have line display limitations
    [string] $enable = "en", #Useful for appliances like Cisco switches that have an 'enable' command mode
    [string] $enablepassword = "",
    [string] $command1 = "show run", #You can add additional commands below here with additonal strings if you want
    [string] $command2 = " ",
    [string] $command3 = " ",
    [string] $command4 = " ",
    [string] $command5 = " ",
    [int] $commandDelay = 1000
   )
 
[string] $output = ""
 
## Read output from a remote host
function GetOutput
{
  ## Create a buffer to receive the response
  $buffer = New-Object System.Byte[] 4096
  $encoding = New-Object System.Text.AsciiEncoding
 
  $outputBuffer = ""
  $foundMore = $false
 
  ## Read all the data available from the stream, writing it to the
  ## output buffer when done.
  do
  {
    ## Allow data to buffer for a bit
    Start-Sleep -m 1000
 
    ## Read what data is available
    $foundmore = $false
    $stream.ReadTimeout = 1000
 
    do
    {
      try
      {
        $read = $stream.Read($buffer, 0, 1024)
 
        if($read -gt 0)
        {
          $foundmore = $true
          $outputBuffer += ($encoding.GetString($buffer, 0, $read))
        }
      } catch { $foundMore = $false; $read = 0 }
    } while($read -gt 0)
  } while($foundmore)
 
  $outputBuffer
}
 
function Main
{
    param ($ip,$port)
  ## Open the socket, and connect to the computer on the specified port
 
  Write-Host "Connecting to $ip on port $port"


  $socket = New-Object System.Net.Sockets.TcpClient($ip, $port)
  
 
  Write-Host "Connected. Press ^D followed by [ENTER] to exit.`n"
 
  $stream = $socket.GetStream()
 
  $writer = New-Object System.IO.StreamWriter $stream
 
    ## Receive the output that has buffered so far
    $SCRIPT:output += GetOutput
 
        $writer.WriteLine($username)
        $writer.Flush()
        Start-Sleep -m $commandDelay
                $writer.WriteLine($password)
        $writer.Flush()
        #Start-Sleep -m $commandDelay
                #$writer.WriteLine($termlength)
        #$writer.Flush()
        Start-Sleep -m $commandDelay
                $writer.WriteLine($enable)
        $writer.Flush()
        Start-Sleep -m $commandDelay
                $writer.WriteLine($enablepassword)
        $writer.Flush()
        Start-Sleep -m $commandDelay
                $writer.WriteLine($command1) #Add additional entries below here for additional 'strings' you created above
        $writer.Flush()
        Start-Sleep -m $commandDelay
                $writer.WriteLine($command2) #Add additional entries below here for additional 'strings' you created above
        $writer.Flush()
                Start-Sleep -m $commandDelay
                $writer.WriteLine($command3) #Add additional entries below here for additional 'strings' you created above
        $writer.Flush()
                Start-Sleep -m $commandDelay
                $writer.WriteLine($command4) #Add additional entries below here for additional 'strings' you created above
        $writer.Flush()
                Start-Sleep -m $commandDelay
                $writer.WriteLine($command5) #Add additional entries below here for additional 'strings' you created above
        $writer.Flush()
        Start-Sleep -m $commandDelay
        $SCRIPT:output += GetOutput
                
 
 
  ## Close the streams
  $writer.Close()
  $stream.Close()

  #building file name
  $filename = "c:\switch\$ip - " + $timestamp + ".txt"
 
  $output | Out-File $filename  #Change this to suit your environment
}

#build the list of ips to be interegated 
$ips = "192.168.1.2","169.254.2.2","192.168.1.101"

#building a file path
$timestamp = get-date -Format g | foreach {$_ -replace ":","."}

#building different file paths for different functions
$errortimestamp = Get-Date -Format o | foreach {$_ -replace ":", "."}
$errorfilename = "c:\switch\" + $timestamp + " - ERROR.txt"

#building different file paths for different functions
$blockedtimestamp = Get-Date -Format o | foreach {$_ -replace ":", "."}
$blockedfilename = "c:\switch\" + $timestamp + " - blocked.txt"

#looping through each ip in ip list
foreach ($ip in $ips)
{
    Write-host "Testing $ip"
    #test to see if device is responding to pings
	if (Test-Connection $ip -Quiet)
    {
        #creating connection on port 23
		$t = New-Object Net.Sockets.TcpClient
		$t.Connect($ip, 23)

        #if it connects, runs the required function with the ip
		if ($t.Connected)
		{
			. Main $ip "23"
		}
        #script block for device responding to ping, but port 23 is NOT open
		else
		{
			$portblocked = "Port 23 on $ip is closed , You may need to contact your IT team to open it. "
            Add-Content $blockedfilename "`n$portblocked"
		}
    }
    #script block for NO RESPONSE
	else 
	    {
    	$errorfilename = "c:\switch\" + $timestamp + " - ERROR.txt" 
        Add-Content $errorfilename "`nCould not ping $ip" 
	    }
}

#displaying information on console
Write-Host "Build file list" -NoNewline
#getting file list to be emailed
$files = Get-ChildItem C:\Switch\ | Where {-NOT $_.PSIsContainer} | foreach {$_.fullname}
#pausing script
Start-Sleep 3
Write-Host "`t" [File List Built] -ForegroundColor "Green"

Write-Host "Sending Email" -NoNewline

#building checks for sending emails

#no error

#replace as needed
$to = "<to>"
$from = "<from>"
$smtpserver = "<smtpserver>"

try
{
    Send-MailMessage -Attachments $files -to $to -from $from -Subject "Network Config backup - $timestamp" -SmtpServer $smtpserver -ErrorAction Stop
    Write-Host "`t [Email Sent]" -ForegroundColor "Green"
}
#error
catch
{
    $ErrorMessage = $_.Exception.Message
    #$ErrorMessage
    if ($ErrorMessage -ne $null)
    {
        Write-Host "`t [Unable to send Mail]" -ForegroundColor "Red"
        Write-Host "There was an error: $ErrorMessage" -ForegroundColor "Yellow"
    }
}

Start-Sleep 3
Write-Host "Removing Files" -NoNewline
$files | Remove-Item
Write-Host "`t [Files removed]" -ForegroundColor "Green"


(E-Mail me)

Follow me.

Facebook (Personal)

Twitter (Personal & System Centre)

Twitter (System Centre Focused)

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s