Cisco IOS Audit PowerShell Script

I had a requirement to do a quick and dirty audit of some IOS devices for a customer.

wanting to do something quick i thought i would use PowerShell as it has all (Well most) of the features of .net but in a scripting language.

so this is what i came up with.

<#
.SYNOPSIS
    Simple Script for the purpose of quickly auditing cisco IOS devices (Gateways / Switches etc.).
    Mark Salter – 11/12/2013
.DESCRIPTION
    I wrote this script to help me audit a lot of devices which are stored in a csv file
    the csv file needs to be in the format
    hostname,portnumber,username,password,enable
    1.1.1.1,23,bob,password,password
    Note about Password: If you have a dollar sign in your password you MUST
    escape it in order for it to work:
        Example:  “$ecurePa$$word
                  This will not work!
        Example:  `$ecurePa`$`$word
                  This WILL work
    You also need to make sure you supply the correct parameters to allow for sucessful operation
    -CsvPath         = Path to the csv file detailed above
    -ConsoleCommands = Commands to execute once logged in
    -OutputLocation  = Location of all output file , these are based on the hostname in the csv file  
.PARAMETER ConsoleCommands
    An array with a single command in each element. 

.PARAMETER OutputLocation
    Location of final out files in the format of C:\Folder
.PARAMETER WaitTime
    The amount of time the script waits in between issuing commands, in Milliseconds.
    When you run this script you must take a look at the output file to make sure
    you got all of the output you want.  If things are cut off then the script is
    running too quickly and you have to slow it down by using a higher number.
    1000 milliseconds is 1 second.
.PARAMETER LoginType
    [Required] This Parameter allows you to  provision for all login types Username or just plain passwords you need to make sure you use the correct login type
    Login Types
    1 = Username, Password, Level 15 access no enabled needed
    2 = Username, Password, Enabled Password
    3 = Password, Enabled Password
.PARAMETER CsvPath
    Path to where you want to store the output files on the disk or network share
.INPUTS
    String input from Pipeline.

.OUTPUTS
    Text file at specified location.
.EXAMPLE
    .\Audit-Me.ps1 -CsvPath “C:\Powershell\Audit-me.csv” -LoginType 2
    The very basic form of running the program this will gather all the defaults
    show run all
    show version
    show diags
    and create the files in the root of the c drive on your computer
    default wait time of 1000 milliseconds
    Login Type will be 1 – See Login Type
.EXAMPLE
    .\Audit-Me.ps1 -CsvPath “C:\Powershell\Audit-me.csv” -ConsoleCommands “show run all”,”show ver”,”show diag” -OutputLocation “C:\Powershell\Audit” -LoginType 2 -WaitTime 1000
    All parameter can be set to give you the exact output you require
.EXAMPLE
    Most Common Useage is like this for most enviroments
    .\Audit-Me.ps1 -CsvPath “C:\Powershell\Audit-me.csv” -OutputLocation “C:\Powershell\Audit” -LoginType 2
    This will give you a good view of all the information on the router / switch
#>
Param (
        [Parameter(ValueFromPipeline=$true)]
        [string[]]$ConsoleCommands = @(“show run”,”show version”,”show diag”),
        [string]$OutputLocation = “C:”,
        [int]$WaitTime = 1000,
        [int]$LoginType = 2,
        [string]$CsvPath = “C:\Powershell\Audit-me.csv”,
        [bool]$UseCsv = 1
    )
    # Get CSv Data for Hosts
    $Hosts = Import-Csv $CsvPath
    $FailedHosts = @()
    Write-Host “Starting Data Capture”
        ForEach ($Item in $Hosts)
        {
            #Attach to the remote device, setup streaming requirements
            try {
                        $Socket = New-Object System.Net.Sockets.TcpClient($Item.hostname, $Item.portnumber)  
                        Write-Host “Connected to Host ” $Item.hostname ” on port ” $Item.portnumber
                        $Stream = $Socket.GetStream()
                        $Writer = New-Object System.IO.StreamWriter($Stream)
                        $Buffer = New-Object System.Byte[] 1024
                        $Encoding = New-Object System.Text.AsciiEncoding
                        switch($LoginType)
                        {
                            1 {
                                $Commands = @($Item.username, $Item.password, “term len 0”)
                                ForEach($c in $ConsoleCommands){$Commands += $c}
                                $Commands += “term len 50”
                              }
                            2 {
                                $Commands = @($Item.username, $Item.password, “en”, $Item.enable, “term len 0”)
                                ForEach($c in $ConsoleCommands){$Commands += $c}
                                $Commands += “term len 50”
                              }
                            3 {
                                $Commands = @($Item.password, “en”, $Item.enable, “term len 0”)
                                ForEach($c in $ConsoleCommands){$Commands += $c}
                                $Commands += “term len 50”
                              }
                            default {
                                        Write-Host “Please Enter a Valid Login Type”
                                        break
                                    }
                        }
                        #Now start issuing the commands
                        ForEach ($Command in $Commands)
                        {  
                            #Enable the line below by removing the hash to debug what commands are being sent to the device
                            #Write-Host “Sending Command – ” + $Command
                            $Writer.WriteLine($Command)
                            $Writer.Flush()
                            Start-Sleep -Milliseconds $WaitTime
                        }
                        #All commands issued, but since the last command is usually going to be
                        #the longest let’s wait a little longer for it to finish
                        Start-Sleep -Milliseconds ($WaitTime * 4)
                        $Result = “”
                        #Save all the results
                        While($Stream.DataAvailable)
                        {   $Read = $Stream.Read($Buffer, 0, 1024)
                            $Result += ($Encoding.GetString($Buffer, 0, $Read))
                        }
                    #Build the output path using the hostname
                    $OutputPath = $OutputLocation + “\” + $Item.hostname + “.txt”
                    #Done, now save the results to a file
                    Write-Host “Writing File ” $OutputPath
                    $Result | Out-File $OutputPath
            }
            catch
            {
                Write-Host “Something Went Wrong While Processing Host” $Item.hostname “Moving On !!!”
                $FailedHosts += $Item.hostname
            }
        }
            Write-Host “Data Capture Finshed”
            if ($FailedHosts -ne “”)
            {
                Write-Host “————————- Error Log ————————-”
                Write-Host “A Number of Hosts Failed and are listed Below”
                Write-Host “”
                ForEach ($fh in $FailedHosts)
                {
                    Write-Host $fh
                }
            }

Download Link – for anyone who wants it Smile

just to note thanks to all the people who have published the sources i used to piece this together.

Leave me a Comment

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 )

Connecting to %s

%d bloggers like this: