cancel
Showing results for 
Search instead for 
Did you mean: 
Create Post
Level 7

Avaya G250/G350 Media Gateways...

Jump to solution

Has anyone created a custom script for Kiwi Cat Tools that works with the Avaya G250/G350 Media Gateways?

I am currently working to create one. It seems to run fine, but the config file stored is blank. I was hoping someone out there already found a solution for this. I will keep working on it and post the config if I am able to get it working correctly.

 

Thanks.

0 Kudos
1 Solution

Hi Toosober,

You could post the script and ini in a zip file on the thwack content exchange in the Kiwi CatTools custom device script section.

With respect to the time stamp you should be able to get around this by using ignore text. In the Function 'Activity_BackupRunningConfig' function there is a section as outlined below and you should be able to add your own ignore text. You will need to redimension the array if you add additional items or replace the existing ignore text items with ones specific to your output;

    ' Set the configuration lines (or text within a line) that should be ignored by the compare process
    sIgnoreText = ""
   
    ReDim rgIgnoreText(3) ' ReDeclare the array with 4 elements (*NOTE: arrays are 0 based).  Increment if more ignore text elements are added
    rgIgnoreText(0) = "^" & "! last configuration change at"
    rgIgnoreText(1) = "^" & "! nvram config last updated at"
    rgIgnoreText(2) = "^" & "ntp clock-period"
    rgIgnoreText(3) = "<" & "! No configuration change since last restart"
    'rgIgnoreText(4) = "...add an instruction here" & "... and ignore text here"
    
    'Ignore instructions define the context of the ignore text.
    '   ^ is the instruction to ignore lines with the sample text occurring anywhere in them
    '   < is the instruction to ignore lines that begin with the sample text
    '   > is the instruction to ignore lines that end with the sample text
   
    ' Join the above ignore text array elements
    sIgnoreText = Join(rgIgnoreText, "|")

View solution in original post

0 Kudos
8 Replies
Level 12

Hi toosober,

Respect to you for using the custom scripting. In CatTools you can create a device capture file when you run your script which will help you see what's happenning.

A device capture file records the communication between CatTools and the device you are having trouble with. You can create a device capture file as follows :

# Use the CatTools File menu to select the "Enable capture mode" option.
# Run the activity you are having trouble with. This should create a debug file in the \Debug folder.

Reading the debug files is a bit of a black art but it should show you whether the config is being generated or whether your script is 'falling down' before this point.

Kind regards,

Wardini

Thanks Wardini for the tip on debugging. It turns out my script is failing as you thought. I will have to keep working on it.

 

Thanks!

0 Kudos

I'm new toCatTools, and we have some Avaya G250/G350 Gateways.  I'd be very interested in getting a copy of your script if you get it working so we could include them with our backups of our network switches.

0 Kudos

I worked with Paul O'Rourke at Solar Winds and he was able to get it working. The only problem is the Avaya config has a timestamp so everytime it runs the G250/350's show up as "changed". Also, occasionally they fail, but I am fine with that. I don't see a way to upload, so I will copy and paste the 2 files. The bold heading is the actual filename. Hope they work for you.

Custom Avaya MediaGateway.ini

[info]
cookie=Kiwi CatTools
version=3
author=Kiwi Enterprises

[device]
name=Custom.Avaya.MediaGateway
id=4000

# Device info

[item_Group]
name=Group
default=Default
required=1
info="The logical group that this device belongs to."

[item_Name]
name=Name
default=Custom Device Template
required=1
info="A unique name for this device. e.g. sales-router or head-office-3500."

[item_HostAddress]
name=Host Address
default=127.0.0.1
required=1
info="IP address or host name of the device."

[item_Filename]
name=File Name
default=
required=1
info="The base file name to use for this device (unique)."

[item_Model]
name=Model
default=G250/G350
required=0
info="The device model number."
list=Custom

[item_ConnectVia]
name=Connect via
default=Direct connect
required=1
info="The name of another device to connect to first."

[item_Telnet]
name=Method
default=Telnet
required=1
list=Telnet,Cisco SSH,SSH1,SSH2,SSH2-nopty,SSH1-DES,SSH1-3DES,SSH1-Blowfish
info="Connection method to use."

[item_TelnetPort]
name=Port
default=23
required=1
list=23,22
info="Port number to use."

# Passwords

[item_VTYPass]
name=VTY Password
default=
required=0
info="VTY password."

[item_EnablePass]
name=Enable Password
default=
required=0
info="Enable or privilege password."

[item_PrivilegeLevel]
name=Privilege Level
default=
required=0
info="Sets the enable mode privilege level. (Not required in most cases)"

[item_ConsolePass]
name=Console Password
default=
required=0
info="The console (com port connection) password."

[item_AAAUsername]
name=Username
default=
required=0
info="AAA/TACACS/RADIUS/Local username."

[item_AAAPassword]
name=Password
default=
required=0
info="AAA/TACACS/RADIUS/Local password."

[item_SNMPRead]
name=SNMP Read
default=
required=0
info="SNMP Read community name."

[item_SNMPWrite]
name=SNMP Write
default=
required=0
info="SNMP Write community name."

[item_RequireVTYLogin]
name=Initial login requires password
default=1
required=0
info="This device requires an initial password for access"

[item_LoginUsesAAA]
name=Initial login requires username/password
default=0
required=0
info="The initial access requires a username and password"

[item_EnableUsesAAA]
name=Enable mode requires username/password
default=0
required=0
info="Enable mode access requires a username and password"

# Prompts

[item_VTYPrompt]
name=VTY Prompt
info="Expected VTY prompt from the device. (Only required if non standard prompt is used)"

[item_EnablePrompt]
name=Enable Prompt
info="Expected enable mode prompt from the device. (Only required if non standard prompt is used)"

[item_ConsolePrompt]
name=Console Prompt
info="Expected console prompt from the device. (Only required if non standard prompt is used)"

[item_AAAUserPrompt]
name=Username prompt
info="Expected Username prompt from the device or AAA server. (Only required if non standard prompt is used)"

[item_AAAPassPrompt]
name=Password prompt
info="Expected AAA Password prompt from the device or AAA server. (Only required if non standard prompt is used)"

# Contact info

[item_Address1]
name=Address1
default=
required=0
info="Location of the device"

[item_Address2]
name=Address2
default=
required=0
info="Location of the device"

[item_Address3]
name=Address3
default=
required=0
info="Location of the device"

[item_ContactName]
name=Contact Name
default=
required=0
info="The name of the person responsible for this device."

[item_ContactPhone]
name=Contact Phone
default=
required=0
info="How to contact the person responsible for this device"

[item_ContactEmail]
name=Contact E-mail
default=
required=0
info="How to contact the person responsible for this device"

[item_ContactOther]
name=Contact Other
default=
required=0
info="Any additional contact info"

[item_AlertEmail]
name=Alert e-mail
default=
required=0
info="Who to notify by e-mail of any alarms or alerts for this device"

[item_SerialNumber]
name=Serial number
default=
required=0
info="The serial number of this device"

[item_AssetTag]
name=Asset Tag
default=
required=0
info="Asset tag information"

[item_Identification]
name=Identification
default=
required=0
info="Identification info for this device"

[item_SerialOther]
name=Other info
default=
required=0
info="Any other serial number information"

[item_ActivitySpecific1]
name=Activity Specific1
default=
required=0
info="Information specific to a particular activity"

[item_ActivitySpecific2]
name=Activity Specific2
default=
required=0
info="Information specific to a particular activity"

Custom Avaya MediaGateway.txt

Attribute VB_Name = "Dev_CustomDeviceTemplate"
Option Explicit

Private Const SCRIPT_NAME = "Device Template"
Private Const DEVICE_USERNAMEPROMPT ="Login:"
Private Const DEVICE_PASSWORDPROMPT = "Password:"
Private Const DEVICE_STANDARDPROMPT = "#"
Private Const DEVICE_PRIVILEGEDPROMPT = ""
Private Const DEVICE_CONFIGPROMPT = ""
Private Const DEVICE_MORETEXT = "--type q to quit or space key to continue--"
 
Private Const DEVICE_INVALIDCOMMAND = "Command not found, try: help"    ' Get this by typing BlahBlahBlah<cr>
Private Const DEVICE_INCOMPLETECOMMAND = "Incomplete command , try help"        ' Get this by typing Copy<cr>
Private Const DEVICE_YESNOTEXT = "(Y/N)?"
Private Const DEVICE_CONFIGHEADERTEXT = "Generating configuration:"    ' Text to trim off the top of a config output before saving it.  Set to "" if no header to remove.

' If device does not have a command then set to ""
Private Const COMMAND_ENTERENABLEMODE = ""
Private Const COMMAND_EXITENABLEMODE = ""
Private Const COMMAND_ENTERCONFIG = ""
Private Const COMMAND_EXITCONFIG = ""
Private Const COMMAND_DISABLEPAGING = "terminal length 200"
Private Const COMMAND_ENABLEPAGING = "terminal length 24" ' Set back to the device default of 24 lines per page
Private Const COMMAND_RUNNINGCONFIG = "show run"
Private Const COMMAND_STARTUPCONFIG = "show start"
Private Const COMMAND_SAVENVRAM = "copy running-config startup-config"
Private Const COMMAND_DISCONNECT = "exit"  ' * The command used to end the session on the device (logout/logoff/exit, etc.)
Private Const COMMAND_TIMEOUT = 30  ' in seconds.  It is not recommended you alter this default value.
 
' ------------------------------------------------- SCRIPT NOTES -------------------------------------------------
'
' CONSTANTS: (user to review and amend accordingly for the custom device).
'   The above declared Constants are based on commands supported by a Cisco router.
'   When setting up your custom device, modify these Constants to suit your device.
'   If the command is not valid for your device, set the Constant value to be an empty string.
'   Do NOT delete the Constant, it may be referenced in the script, even if no value is set.
'   If not declared errors could occur at run-time.
'   * NOTE: ensure the COMMAND_DISCONNECT is correct for your device otherwise the device may respond with an
'   invalid command message and therefore fail your activity.
'
' TASKS TO COMPLETE DURING INITIAL SCRIPT SETUP: (user to complete).
'   Function: SendPassword
'      rgMult(2) is set to the initial value of "Incorrect Password!", valid for a Cisco Router.
'      Please change rgMult(2) accordingly for your device.
'
' ADDITIONAL TASKS POST INITIAL SCRIPT SETUP: (user to update as and when encountered).
'   Function: SendPassword
'      Add any additional rgMult() items you encounter when sending the password or logging on to the device.
'   Function: SendUsername
'      Add any additional rgMult() items you encounter when sending the username or logging on to the device.
'
' FUNCTIONS:
'   Each function header contains a list of functions/procedures called from within the function.
'   This list excludes calls to any of the internal CatTools functions which are prefixed with "cl."
'   A full list of cl. functions exposed to the template including a brief description and example how to
'   use them can be found in our one line help file at http://www.kiwisyslog.com/help/cattools/index.html
'
' ------------------------------------------------- DEVICE NOTES -------------------------------------------------
'
' CUSTOM SCRIPT: Cisco Router (overwrite with your device name)
'   This is a custom device script for a Cisco Router...[add your device information here]
'
'
' Custom activity added
'
' ------------------------------------------------- END OF NOTES -------------------------------------------------


Function login()
' The Function Login() is the initial entry point for a login to a device.
' It queries the connection method specified in the device setup, and redirects to the relevant login function.
' If login successful it calls on a function to determine the device hostname.
'
' Calls On:         LoginTelnet, LoginSSH, DetermineHostname
'
' Date Created:     [AutoGenDateScriptCreated]
' Modifications:    (Date - Description of changes)

   
    ' Declare variables
    Dim bLoginOK
   
    ' Initialise client variables
    cl.Initialise

    ' Default function return value
    login = False
   
    ' Send level 4 (debug) message to infolog
    cl.Log 4, "Login " & SCRIPT_NAME & ": " & cl.CurDevName
   
    ' Query device connection method and redirect to relevant login function
    Select Case LCase(Left(cl.CurDevTelnet, 3))
    Case "tel"
        bLoginOK = LoginTelnet
    Case "ssh"
        bLoginOK = LoginSSH
    Case Else
        ' Unknown
    End Select
   
    If bLoginOK = True Then
        ' Successful login
        cl.Log 4, "Login to " & cl.CurDevName & " was successful"
       
        ' Call function to determine the device hostname
        If DetermineHostname = True Then
            cl.Log 4, "DeviceHostnameID: " & cl.DeviceHostnameID
            login = True
        End If
   
    Else ' Failed login
        cl.Log 4, "Login to " & cl.CurDevName & " failed"
    End If
   
End Function


Function LoginTelnet()
' The Function LoginTelnet() is called if connecting to the device using Telnet.
' It reads the response buffer from the device and redirects to the relevant login authentication function.
'
' Calls On:         LoginAAA, SendPassword
'
' Date Created:     [AutoGenDateScriptCreated]
' Modifications:    (Date - Description of changes)
   
   
    ' Declare variables
    Dim rgMult     ' array of multiple items
    Dim iRetVal
    Dim bSentCR
    Dim bContinue

    ' Default function return value
    LoginTelnet = False
   
    ' Redimension rgMult to number of response items we are testing for (increment accordingly when adding new values)
    ' *Note: rgMult is really a 0 (zero) based array.  Element rgMult(0) is not specified as this is returned by the
    ' function if none of the others elements are found
    ReDim rgMult(5)
   
    ' Expected possible default return values in order we want to test for them
    rgMult(1) = DEVICE_USERNAMEPROMPT
    rgMult(2) = DEVICE_PASSWORDPROMPT
    'rgMult(3) = ... add additional rgMults if required
   
    ' Override defaults if required (i.e. custom prompts set in device setup - Prompts tab)
    If Len(cl.CurDevAAAUserPrompt) > 0 Then rgMult(1) = cl.CurDevAAAUserPrompt
    If Len(cl.CurDevVTYPrompt) > 0 Then rgMult(2) = cl.CurDevVTYPrompt
   
    ' If the device has no user security then check for just the device prompts (i.e. getting straight in after connection)
    ' *NOTE: This is not a recommended configuration for your device.  The script may have undesirable results if these
    ' chars exist in your device banner
    If cl.CurDevRequireVTYLogin = "0" And cl.CurDevLoginUsesAAA = "0" Then
        ' *NOTE: Always set device prompts as last items to check for
        rgMult(4) = DEVICE_STANDARDPROMPT
        rgMult(5) = DEVICE_PRIVILEGEDPROMPT
    End If
   
    ' Default the variables and start the login process
    bSentCR = False
    bContinue = True
   
    Do While bContinue = True
        ' Only loop back if instructed to do so
        bContinue = False
       
        ' Compare device response buffer to our response array (rgMult). Each Case below refers to the rgMults above.
        iRetVal = cl.WaitForMultData(rgMult, , COMMAND_TIMEOUT)
       
        Select Case iRetVal
        Case 0 ' Device response not one we are expecting
            ' Check if response buffer is empty or not
            If Len(cl.RxBuffer) = 0 Then
                ' Send a <CR> to try 'wake the device up'. *NOTE: do only the once
                If Not bSentCR Then
                    cl.SendData vbCr
                    bSentCR = True
                    bContinue = True
                Else ' Still no device response
                    cl.Log 1, "Did not receive VTY entry prompt from " & SCRIPT_NAME & " after CR"
                End If
            Else
                ' Check for devices that have no VTY sessions available and therefore log you straight in
                If Right(cl.RxBuffer, Len(DEVICE_STANDARDPROMPT)) = DEVICE_STANDARDPROMPT Then
                    ' No sessions were available, but we have been logged in
                    cl.Log 4, "No password was required to login to " & SCRIPT_NAME
                Else
                    ' Login failed - report the results
                    If cl.CurDevLoginUsesAAA = "1" Then
                       cl.Log 1, "Did not receive Login entry prompt from " & SCRIPT_NAME
                    Else
                       cl.Log 1, "Did not receive VTY entry prompt from " & SCRIPT_NAME
                    End If
                End If
            End If
        Case 1 ' Username prompt received - do a username and password login
            If LoginAAA = True Then LoginTelnet = True
        Case 2 ' Password prompt received - do a password only login
             If SendPassword("LOGINVTY") = True Then LoginTelnet = True
        Case 4, 5 ' Logged in with no authentication
             cl.Log 4, "No VTY password was required to login to " & SCRIPT_NAME
        End Select
    Loop
   
End Function


Function LoginAAA()
' The Function LoginAAA() is called when authenticating to a device using AAA/TACACS/RADIUS or Local username/password authentication.
'
' Calls On:         SendUsername
'                   SendPassword
'
' Date Created:     [AutoGenDateScriptCreated]
' Modifications:    (Date - Description of changes)
   
    ' Declare variables
    Dim iLoginAttempts
   
    ' Default function return value
    LoginAAA = False
   
    cl.Log 4, "Beginning LoginAAA"
   
    ' Try 3 times to log in - sometimes RADIUS sends failure with correct data due to inability to handle multiple simutaneous login requests
    For iLoginAttempts = 1 To 3
        If SendUsername("LOGINAAA") = True Then
            ' Login was successful, so now send password
            If SendPassword("LOGINAAA") = True Then
                ' Password accepted, we are authenticated
                LoginAAA = True
                Exit For
            Else
                ' Authentication failed after sending password
                cl.Log 2, "LoginAAA authentication failed - will retry"
                ' Pause for 3 seconds
                cl.Delay 3
            End If
        Else
            ' No password prompt received after sending username to device
            ' Check the last character of what the receive buffer
            If Len(cl.RxBuffer) > 0 Then
                If Mid(cl.RxBuffer, Len(cl.RxBuffer) - Len(DEVICE_STANDARDPROMPT) + 1) = DEVICE_STANDARDPROMPT Or _
                   Mid(cl.RxBuffer, Len(cl.RxBuffer) - Len(DEVICE_PRIVILEGEDPROMPT) + 1) = DEVICE_PRIVILEGEDPROMPT Then
                    ' A device prompt was received, so assume no password was needed to authenticate
                    LoginAAA = True
                    Exit For
                Else
                    ' Something other then device prompts was received - retry
                End If
            End If
            ' We received something unknown - retry
            cl.Log 2, "LoginAAA username failed - will retry"
        End If
    Next

End Function


Function LoginSSH()
' The Function LoginSSH() is called when authenticating to a device using SSH.
'
' Calls On:         LoginAAA
'                   SendPassword
'
' Date Created:     [AutoGenDateScriptCreated]
' Modifications:    (Date - Description of changes)
   
' For SSH login:
' Username and Password are compulsory but the values are encoded as part of the protocol, so all we do is wait.
' Once the connection is established we should get the prompt in the response buffer.
   
    ' Declare variables
    Dim rgMult
    Dim iRetVal
    Dim bSentCR
    Dim bStillProcessing
  
   
    ' Default function return value
    LoginSSH = False
   
    cl.Log 4, "LoginSSH waiting for command prompt"
        
    ' Redimension rgMult to number of response items we are testing for (increment accordingly when adding new values)
    ReDim rgMult(4)
  
    ' Expected possible default return values in order we want to test for them
    rgMult(1) = DEVICE_STANDARDPROMPT
    rgMult(2) = DEVICE_PRIVILEGEDPROMPT
    rgMult(3) = DEVICE_USERNAMEPROMPT
    rgMult(4) = DEVICE_PASSWORDPROMPT
    
    ' Default the variables
    bSentCR = False
    bStillProcessing = True
   
    Do While bStillProcessing
        ' Only loop back if instructed to do so
        bStillProcessing = False
   
        iRetVal = cl.WaitForMultData(rgMult, , COMMAND_TIMEOUT)
   
        Select Case iRetVal
        Case 0
            ' Check if response buffer is empty, then send a <CR> to try 'wake' the device up - *NOTE: only try this once
            If Len(cl.RxBuffer) = 0 Then
                If bSentCR = False Then
                    cl.SendData vbCr
                    bSentCR = True
                    bStillProcessing = True
                Else
                    cl.Log 1, "Did not receive command prompt after connecting via SSH after CR"
                End If
            Else
                cl.Log 1, "Did not receive command prompt after connecting via SSH"
            End If
        Case 1, 2
            ' A device prompt has been received - Login SSH successful
            LoginSSH = True
        Case 3
            ' We received a username prompt - go through the AAA login
            LoginSSH = LoginAAA
        Case 4
            ' We received a password prompt after SSH login - go through a VTY login
            LoginSSH = SendPassword("LOGINVTY")
        End Select
    Loop

End Function


Function LoginCV(sConnectTo, sConnectFrom)
    Call cl.CatToolsNoSupport
End Function


Function LoginCVSSH()
    Call cl.CatToolsNoSupport
End Function


Function SendPassword(sWhichPassword)
' The Function SendPassword() is called when a password prompt is received from the device.
' It sends the relevant password from the device setup information to the device and waits for the response.
'
' Calls On:         N/A
'
' Date Created:     [AutoGenDateScriptCreated]
' Modifications:    (Date - Description of changes)
   
   
    ' Declare variables
    Dim rgMult
    Dim iRetVal
   
    ' Default function return value
    SendPassword = False
   
    ' Redimension rgMult to number of response items we are testing for (increment accordingly when adding new values)
    ReDim rgMult(5)
   
    ' Expected possible default return values in order we want to test for them
    rgMult(1) = DEVICE_PASSWORDPROMPT
    rgMult(2) = "Login incorrect"
    'rgMult(3) = ... add additional rgMults if required

    ' *NOTE: Set device prompts last
    rgMult(4) = DEVICE_STANDARDPROMPT
    rgMult(5) = DEVICE_PRIVILEGEDPROMPT
   
    ' Flush the response buffer
    cl.FlushRxBuffer
       
    ' Send the relevant password
    Select Case sWhichPassword
    Case "LOGINVTY"
        ' Override default VTY Password prompt if required (i.e. custom VTY prompt set in device setup - Prompts tab)
        If Len(cl.CurDevVTYPrompt) > 0 Then rgMult(1) = cl.CurDevVTYPrompt
        cl.Log 4, "Sending login VTY password"
        cl.SendData cl.CurDevVTYPass & vbCr
    Case "LOGINAAA"
        ' Override default if required (i.e. custom Password prompt set in device setup - Prompts tab)
        If Len(cl.CurDevAAAPassPrompt) > 0 Then rgMult(1) = cl.CurDevAAAPassPrompt
        cl.Log 4, "Sending login AAA password"
        cl.SendData cl.CurDevAAAPassword & vbCr
    Case "ENABLEVTY"
        ' Override default if required (i.e. custom Enable prompt set in device setup - Prompts tab)
        If Len(cl.CurDevEnablePrompt) > 0 Then rgMult(1) = cl.CurDevEnablePrompt
        cl.Log 4, "Sending enable password"
        cl.SendData cl.CurDevEnablePass & vbCr
    Case "ENABLEAAA"
        ' Override default if required (i.e. custom Password prompt set in device setup - Prompts tab)
        If Len(cl.CurDevAAAPassPrompt) > 0 Then rgMult(1) = cl.CurDevAAAPassPrompt
        cl.Log 4, "Sending enable AAA password"
        cl.SendData cl.CurDevAAAPassword & vbCr
    Case Else
        cl.Log 4, "Did not know which password to send"
        Exit Function
    End Select
           
    ' Compare device response buffer to our response array (rgMult)
    iRetVal = cl.WaitForMultData(rgMult, , COMMAND_TIMEOUT)
    Select Case iRetVal
        Case 1, 2
            ' Failed - invalid password, or password prompt received back from device
            cl.Log 1, "Password is incorrect for device"
        Case 4, 5
            ' Login accepted - a valid device prompt was received back
            SendPassword = True
        Case Else
            ' Unexpected response received back from device
            cl.Log 1, "Did not receive expected response after sending password"
    End Select

End Function


Function SendUsername(sWhichUsername)
' The Function SendUsername() is called when a username prompt is received from the device.
' It sends the username from the device setup information to the device and waits for the response.
'
' Calls On:         N/A
'
' Date Created:     [AutoGenDateScriptCreated]
' Modifications:    (Date - Description of changes)
   
   
    ' Declare variables
    Dim rgMult
    Dim iRetVal
   
    ' Default function return value
    SendUsername = False
   
    ' Redimension rgMult to number of response items we are testing for (increment accordingly when adding new values).
    ReDim rgMult(5)
   
    ' Expected possible default return values in order we want to test for them
    rgMult(1) = DEVICE_PASSWORDPROMPT
    rgMult(2) = DEVICE_USERNAMEPROMPT
    'rgMult(3) = ... add additional rgMults if required.

    ' Set additional rgMults depending on which username we are sending
    Select Case sWhichUsername
    Case "LOGINAAA"  ' Initial login
        cl.Log 4, "Sending login AAA username"
        ' Failed responses when doing an initial AAA login
        rgMult(3) = "% Login invalid"
        rgMult(4) = "% Authentication failed"
    Case "ENABLEAAA"  ' Privileged username
        cl.Log 4, "Sending enable AAA username"
        ' Failed responses when entering enable mode
        rgMult(3) = "Login invalid"
        rgMult(4) = "Access denied"
        rgMult(5) = "Error in authentication"
    Case Else  ' Input parameter not specified or not an expected value
        cl.Log 4, "Missing or invalid username input parameter specified"
        Exit Function
    End Select
   
    ' Override defaults if required (i.e. custom Password and Username prompts set in device setup - Prompts tab)
    If Len(cl.CurDevAAAPassPrompt) > 0 Then rgMult(1) = cl.CurDevAAAPassPrompt
    If Len(cl.CurDevAAAUserPrompt) > 0 Then rgMult(2) = cl.CurDevAAAUserPrompt
       
    ' Flush the buffer
    cl.FlushRxBuffer
   
    ' Send Username and wait for response
    cl.SendData cl.CurDevAAAUsername & vbCr
   
    ' Compare device response buffer to our response array (rgMult)
    iRetVal = cl.WaitForMultData(rgMult, , COMMAND_TIMEOUT)

    ' The desired result is to get a password prompt back after sending username
    If iRetVal = 1 Then  ' i.e. rgMult(1) value - DEVICE_PASSWORDPROMPT
        SendUsername = True
    End If
   
End Function


Function DetermineHostname()
' The Function DetermineHostname() is called to establish and set the following values used as anchor points after a
' command has been sent and its output or response received:
'   cl.DeviceHostnameID        -  the host name of the device
'   cl.DeviceVTYPrompt         -  the host name and ending with DEVICE_STANDARDPROMPT
'   cl.DeviceEnablePrompt      -  the host name and ending with DEVICE_PRIVILEGEDPROMPT
'   cl.DeviceConfigPrompt      -  the host name and ending with DEVICE_CONFIGPROMPT
'
' Calls On:         N/A
'
' Date Created:     [AutoGenDateScriptCreated]
' Modifications:    (Date - Description of changes)
   
    DetermineHostname = cl.DetermineHostname(DEVICE_STANDARDPROMPT, DEVICE_PRIVILEGEDPROMPT, DEVICE_CONFIGPROMPT)
   
End Function


Function SendPostLoginCommands()
' The Function SendPostLoginCommands() is called to issue CLI commands setting the environment post successful login.
' Refer to Function SendPostEnterEnableModeCommands() for examples of the type of code you would enter.
'
' Calls On:         N/A
'
' Date Created:     [AutoGenDateScriptCreated]
' Modifications:    (Date - Description of changes)

    SendPostLoginCommands = True

End Function


Function SendPostEnterEnableModeCommands()
' The Function SendPostEnterEnableModeCommands() is called to issue CLI commands setting the environment after successfully entering Enable mode.
' Below are two examples of the code to disable paging of the command output (i.e. the --More-- prompts)
'
' Calls On:         N/A
'
' Date Created:     [AutoGenDateScriptCreated]
' Modifications:    (Date - Description of changes)
   
   
' #Example 1:
' Sends the command to disable paging if set as constant COMMAND_DISABLEPAGING.
' If the command fails for any reason the function just continues and returns TRUE
'
    If Len(COMMAND_DISABLEPAGING) > 0 Then
        cl.SendAndWaitForPrompt (COMMAND_DISABLEPAGING)
    End If
   
    SendPostEnterEnableModeCommands = True
   
   
' #Example 2:
' Sends the command to disable paging if set as constant COMMAND_DISABLEPAGING.
' If the command fails for any reason the function returns FALSE, else if command is successful or command is not to be issued then returns TRUE
'
'    If Len(COMMAND_DISABLEPAGING) > 0 Then
'        SendPostEnterEnableModeCommands = cl.SendAndWaitForPrompt(COMMAND_DISABLEPAGING) ' TRUE if command successful; FALSE if not (invalid command / privileged level doesn't allow, etc)
'    Else ' No command to send so return TRUE
'        SendPostEnterEnableModeCommands = True
'    End If

End Function


Function SendPreExitEnableModeCommands()
' The Function SendPreExitEnableModeCommands() is called to issue CLI commands resetting the environment before attempting to exit Enable mode.
' Below are two examples of the code to re-enable paging of the command output
'
' Calls On:         N/A
'
' Date Created:     [AutoGenDateScriptCreated]
' Modifications:    (Date - Description of changes)
   
   
' #Example 1:
' Sends the command to re-enable paging if set as constant COMMAND_ENABLEPAGING.
' If the command fails for any reason the function just continues and returns TRUE
'
    If Len(COMMAND_ENABLEPAGING) > 0 Then
        cl.SendAndWaitForPrompt (COMMAND_ENABLEPAGING)
    End If
    SendPreExitEnableModeCommands = True
   
   
' #Example 2:
' Sends the command to re-enable paging if set as constant COMMAND_ENABLEPAGING.
' If the command fails for any reason the function returns FALSE, else if command is successful or command is not to be issued then returns TRUE
'
'    If Len(COMMAND_ENABLEPAGING) > 0 Then
'        SendPreExitEnableModeCommands = cl.SendAndWaitForPrompt(COMMAND_ENABLEPAGING) ' TRUE if command successful; FALSE if not (invalid command / privileged level doesn't allow, etc)
'    Else ' No command to send so return TRUE
'        SendPreExitEnableModeCommands = True
'    End If

End Function


Function SendSessionTerminationCommands()
' The Function SendSessionTerminationCommands() is called to issue CLI commands to reset the environment at session end.
'
' Calls On:         ExitConfigMode
'                   SendPreExitEnableModeCommands
'                   ExitEnableMode
'
' Date Created:     [AutoGenDateScriptCreated]
' Modifications:    (Date - Description of changes)
   
    ' Call function to exit configuration mode if currently in
    ExitConfigMode
   
    ' Call function to exit enable mode
    ExitEnableMode
   
    ' Now send the exit session command
    If Len(COMMAND_DISCONNECT) > 0 Then
        cl.Log 4, "Disconnecting from " & cl.CurDevName
        cl.SendData COMMAND_DISCONNECT & vbCr
    End If
   
End Function


Function EnterEnableMode()
' The Function EnterEnableMode() will attempt to enter priviledged or Enable mode.
'
' Calls On:         EnterEnableModeVTY
'                   EnterEnableModeAAA
'                   SendPostEnterEnableModeCommands
'
' Date Created:     [AutoGenDateScriptCreated]
' Modifications:    (Date - Description of changes)
   
    ' Declare variables
    Dim rgMult
    Dim iRetVal
    Dim sCmd
   
    ' Default response
    EnterEnableMode = False
  
    If Len(COMMAND_ENTERENABLEMODE) = 0 Then
        ' The COMMAND_ENTERENABLEMODE constant not set as the device does not have an Enable mode. Return TRUE.
        EnterEnableMode = True
    Else
        ' Check and see if we are already in Enable mode before trying to go there
        iRetVal = CurrentDeviceContextLevel
        ' 1 = VTY prompt, 2 = Enable prompt, 3 = Config prompt, 0 = Unknown prompt
 
        If (iRetVal = 0) Or (iRetVal = 1) Then
            ' We are at the VTY prompt.  Issue the command to get us into Enable mode
            cl.Log 4, "Entering Enable mode"
       
            ' Default return value and clear the response buffer
            EnterEnableMode = False
            cl.FlushRxBuffer
           
            ' Command to send
            sCmd = COMMAND_ENTERENABLEMODE
           
            ' If device setup specifies a priviledged level, then append to the Enable command (e.g. "Enable 15"),
            If Len(cl.CurDevPrivilegeLevel) > 0 Then
                sCmd = sCmd & " " & cl.CurDevPrivilegeLevel
            End If
           
            ' Type in command and wait for echo
            iRetVal = cl.SendAndWaitForEcho(sCmd)
           
            ' Was command echoed back from the device, if not then Exit
            If iRetVal = False Then Exit Function
           
            ' Command echoed so flush the response buffer ready for command response data
            cl.FlushRxBuffer
           
            ' Send CR to send the command
            cl.SendData vbCr
           
            cl.Log 4, "Waiting for Enable mode password prompt"
               
            ' Redimension rgMult to number of response items we are testing for (increment accordingly when adding new values)
            ReDim rgMult(4)
  
            ' Expected possible default return values in order we want to test for them
            rgMult(1) = cl.DeviceEnablePrompt
            rgMult(2) = cl.DeviceVTYPrompt
            rgMult(3) = DEVICE_PASSWORDPROMPT
            rgMult(4) = DEVICE_USERNAMEPROMPT
           
            ' Override defaults if required (i.e. custom prompts set in device setup - Prompts tab)
            If Len(cl.CurDevEnablePrompt) > 0 Then rgMult(3) = cl.CurDevEnablePrompt
            If Len(cl.CurDevAAAUserPrompt) > 0 Then rgMult(4) = cl.CurDevAAAUserPrompt
           
            ' Analyse the response data from the device after sending the command
            iRetVal = cl.WaitForMultData(rgMult, , COMMAND_TIMEOUT)
           
            Select Case iRetVal
            Case 0 ' No valid data received
                 If cl.CurDevEnableUsesAAA = "1" Then
                    cl.Log 1, "Did not receive expected Username prompt when entering Enable mode"
                 Else
                    cl.Log 1, "Did not receive expected prompt when entering Enable mode"
                 End If
                 Exit Function
            Case 1 ' No Enable password was set or we've got custom Enable prompt
                 cl.Log 4, "Already in Enable mode, or no password was set"
            Case 2 ' unable to enter Enable mode
                 cl.Log 1, "Failed to enter Enable mode"
                 Exit Function
            Case 3, 5 ' Enable password prompt received
                 If EnterEnableModeVTY = False Then Exit Function
            Case 4 ' Username prompt received
                 If EnterEnableModeAAA = False Then Exit Function
            End Select
           
            EnterEnableMode = True
            cl.Log 4, "Entered Enable mode OK"
        Else
            ' We were already in Enable or Config mode
            cl.Log 4, "Skipping enter Enable mode as we are already in Enable mode"
            EnterEnableMode = True
        End If
    End If
    ' Call function to set the environment before exiting enable mode
    SendPostEnterEnableModeCommands
   
End Function


Function EnterEnableModeAAA()
' The Function EnterEnableModeAAA() requires Username and Password to enter Enable mode.
' The command has been sent to enter Enable mode and we have received the Username (or equivilent) prompt.
'
' Calls On:         SendUsername
'                   SendPassword
'
' Date Created:     [AutoGenDateScriptCreated]
' Modifications:    (Date - Description of changes)
   
    EnterEnableModeAAA = False
   
    ' Send the username as specified in the settings
    If SendUsername("ENABLEAAA") Then
        If SendPassword("ENABLEAAA") Then
            EnterEnableModeAAA = True
        End If
    End If
End Function


Function EnterEnableModeVTY()
' The Function EnterEnableModeVTY() requires just Password to enter Enable mode.
' The command has been sent to enter Enable mode and we are at the password prompt.
'
' Calls On:         SendPassword
'
' Date Created:     [AutoGenDateScriptCreated]
' Modifications:    (Date - Description of changes)
   
    ' Send the password as specified in the settings
    If cl.CurDevEnableUsesAAA = "1" Then
       EnterEnableModeVTY = SendPassword("ENABLEAAA")
    Else
       EnterEnableModeVTY = SendPassword("ENABLEVTY")
    End If
   
End Function


Function ExitEnableMode()
' The Function ExitEnableMode() will attempt to exit priviledged or Enable mode.
'
' Calls On:         SendPreExitEnableModeCommands
'
' Date Created:     [AutoGenDateScriptCreated]
' Modifications:    (Date - Description of changes)

    ' Declare variables
    Dim iRetVal
   
    ' Default response
    ExitEnableMode = False

    If Len(COMMAND_EXITENABLEMODE) = 0 Then
        ' The COMMAND_EXITENABLEMODE constant not set as the device does not have an Enable mode. Return TRUE.
        ExitEnableMode = True
    Else
        ' Check and see if we are in Enable mode before trying to exit from it
        iRetVal = CurrentDeviceContextLevel
        ' 1 = VTY prompt, 2 = Enable prompt, 3 = Config prompt, 0 = Unknown prompt

        If iRetVal = 2 Then
            ' We are in enable mode, so call function to reset the environment before exiting enable mode
            SendPreExitEnableModeCommands
           
            cl.Log 4, "Exiting enable mode"
            ' Send command to exit out of Enable mode
            cl.SendAndWaitForPrompt COMMAND_EXITENABLEMODE
            ' Check the context level again to ensure we are out of Enable mode
            If CurrentDeviceContextLevel = 1 Then
                ' Exited OK, so return TRUE
                ExitEnableMode = True
                cl.Log 4, "Exited enable mode OK"
            End If
        End If
       
    End If
   
End Function


Function EnterConfigMode()
' The Function EnterConfigMode() will attempt to enter Configuration mode.
'
' Calls On:         SendCommandSingle
'
' Date Created:     [AutoGenDateScriptCreated]
' Modifications:    (Date - Description of changes)
 
  
    ' Declare variables
    Dim iRetVal
   
    ' Default response
    EnterConfigMode = False
   
    ' Check to see if we not in VTY mode or already in Config mode before trying to enter it
    iRetVal = CurrentDeviceContextLevel
    ' 1 = VTY prompt, 2 = Enable prompt, 3 = Config prompt, 0 = Unknown prompt

    Select Case iRetVal
    Case 0, 2
        ' Check the COMMAND_ENTERCONFIG constant has been set
        If Len(COMMAND_ENTERCONFIG) > 0 Then
            ' Attempt to enter Config mode.  A level 1 error raised if not entered ok
            If SendCommandSingle(COMMAND_ENTERCONFIG, 0, 1, 0) Then
                ' Verify we have entered Config mode OK
                If CurrentDeviceContextLevel = 3 Then
                    EnterConfigMode = True
                End If
            End If
        Else
            ' No value set for the COMMAND_ENTERCONFIG constant, so skip trying to enter.  Assume this is not needed and Return TRUE
            cl.Log 4, "Skipping enter Config mode"
            EnterConfigMode = True
        End If
    Case 1
        ' We are still in VTY mode - Return FALSE
        cl.Log 4, "Can't enter Config mode while in VTY mode"
    Case 3
        ' WE are already in Config mode - Return TRUE
        cl.Log 4, "Already in Config mode"
        EnterConfigMode = True
    End Select
   
End Function
      

Function ExitConfigMode()
' The Function ExitConfigMode() will attempt to exit Configuration mode.
'
' Calls On:         N/A
'
' Date Created:     [AutoGenDateScriptCreated]
' Modifications:    (Date - Description of changes)
   
    ' Declare variables
    Dim iRetVal
    Dim iCount
    Dim iMaxRetries
    Dim sCmd
   
    ' Default response
    ExitConfigMode = True
   
    If Len(COMMAND_EXITCONFIG) = 0 Then
        ' The COMMAND_EXITCONFIG constant was not set, so assume the device does not have a Config mode
    Else
        ' Initialise variables
        iCount = 0
        iMaxRetries = 5
       
        ' Check and see if we are in Config mode before trying to exit from it
        iRetVal = CurrentDeviceContextLevel
        ' 1 = VTY prompt, 2 = Enable prompt, 3 = Config prompt, 0 = Unknown prompt
       
        Select Case iRetVal
        Case 3
            ' We are at the Config mode prompt
            cl.Log 4, "Exiting config mode"
            sCmd = COMMAND_EXITCONFIG
            If sCmd = "CTRL-Z" Then sCmd = Chr(26)
           
            ' Loop sending the command up to number of Attempts specified.
            ' This is used to try exit back to the Enable mode, when we have navigated down the depths of Config mode levels
            Do While (iRetVal = 3) And iCount <= iMaxRetries
                iCount = iCount + 1
                cl.SendData sCmd
                ' Re-evaluate the current context level to see if we are still at a Config prompt
                iRetVal = CurrentDeviceContextLevel
            Loop
            ' We have exceeded the maximum retry limit, so Return FALSE (failed to exit config mode successfully)
            If iCount > iMaxRetries Then ExitConfigMode = False
           
            ' We are back at Enable mode - Return TRUE
            If iRetVal = 2 Then cl.Log 4, "Exited Config mode ok"
       
        Case Else
            ' We were not in Config mode so it wasn't necessary to try exit it
        End Select
   
    End If
   
End Function
 

Function CurrentDeviceContextLevel()
' The Function CurrentDeviceContextLevel() is called by a number of functions within the script to determine
' in which mode the device is currently in.  Normally it is called before sending a command to change to a different mode.
' The function returns a number identifying the current mode by examining the device prompt.
'
' Calls On:         N/A
'
' Date Created:     [AutoGenDateScriptCreated]
' Modifications:    (Date - Description of changes)
   
    ' Declare variables
    Dim rgMult(4)
    Dim iRetVal
   
    ' Flush the response buffer and send a <CR> and see what sort of prompt we get.
    ' This ensures we have a clean buffer with just the prompt in it to then examine
    cl.FlushRxBuffer
    cl.SendData vbCr

    ' Set the possible modes we could be in.
    '*Note: if the device VTY and Enable prompts are the same, it will return the 1st one in the rgMult list below, in this case VTY.
    rgMult(1) = cl.DeviceVTYPrompt
    rgMult(2) = cl.DeviceEnablePrompt
    rgMult(3) = cl.DeviceConfigPrompt
    rgMult(4) = "(config-" ' Config mode prompt. Sometimes used when long hostname prompts are truncated (e.g. "MyCiscoHostna(config-if-range)#")
   
    ' Evaluate the returned data
    iRetVal = WaitForMultData(rgMult, , COMMAND_TIMEOUT)
   
    If iRetVal = 4 Then iRetVal = 3   '3 and 4 are both config mode
   
    ' Return the mode
    CurrentDeviceContextLevel = iRetVal
   
End Function


Function GetConfig(sCmd, sStoredConfig)
' The Function GetConfig() sends a command (sCmd) to capture the device configuration and returns a
' text string (sStoredConfig).
'
' Calls On:         SendCommandSingle
'
' Date Created:     [AutoGenDateScriptCreated]
' Modifications:    (Date - Description of changes)
 

    ' Default function return status
    GetConfig = "Failed"
       
    ' Clear the response buffer
    cl.FlushRxBuffer

    ' Send the command to capture the configuration
    If SendCommandSingle(sCmd, 0, 1, 1) = True Then
       
        ' Copy the results of the command from the response buffer to the variable
        sStoredConfig = cl.RxBuffer
       
        ' Massage the device output:
        '  remove nulls
        sStoredConfig = cl.ReplaceText(sStoredConfig, Chr(0), "")
        '  Check if the DEVICE_CONFIGHEADERTEXT constant has been set
        If Len(DEVICE_CONFIGHEADERTEXT) > 0 Then
            ' Check output for header text and if found remove everything up to and including it
            If cl.TextInText(sStoredConfig, DEVICE_CONFIGHEADERTEXT) Then
                sStoredConfig = cl.TextRemoveTextUpTo(sStoredConfig, DEVICE_CONFIGHEADERTEXT, True)
            End If
        End If
        '  remove padding
        sStoredConfig = Trim(sStoredConfig)
        '  remove blank header lines
        sStoredConfig = cl.TextRemoveBlankHeaderLines(sStoredConfig)
       
        ' Output capture and massage successful.  Set the function return status.
        GetConfig = "OK"
   
    End If
   
End Function


Function SendCommandSingle(sCmd, bYesToConfirm, iErrorLevel, bCleanBuffer)
' The Function SendCommandSingle() sends a command (sCmd) to the device and returns True if command
' executed successfully, False if not.
'
'   sCmd:           a string value being the command to send to the device.
'   bYesToConfirm:  boolean value.
'                   True: a Y (or Yes) will be sent if yes/no prompts are encountered.
'                   False: a N (or No) will be sent if yes/no prompts are encountered.
'   iErrorLevel:    is the level of error to raise if the command fails to execure successfully.
'                   0 will not raise an error.
'   bCleanBuffer:   boolean value.
'                   True: the buffer will be returned with just the results of the command, i.e. prompts and commands trimmed from output.
'                   False: the buffer will be left alone, returning the prompts and commands sent.
'                   *NOTE: "--More--" 'paging' prompts will always be trimmed.
'
' Calls On:         N/A
'
' Date Created:     [AutoGenDateScriptCreated]
' Modifications:    (Date - Description of changes)
   
    ' Declare variables
    Dim rgMult
    Dim iRetVal
    Dim sStoredBuffer
    Dim bCommandExecutedOK
    Dim iTimeoutMultiplier
    Dim sStart 'start position for any data massaging
   
    ' Default function return value
    bCommandExecutedOK = False
   
    ' Set environment variables
    sStoredBuffer = ""
    iTimeoutMultiplier = 1

    ' Redimension rgMult to number of response items we are testing for.
    ReDim rgMult(10)
   
    ' Expected possible default return values in order we want to test for them
    rgMult(1) = DEVICE_MORETEXT
    rgMult(2) = DEVICE_INVALIDCOMMAND
    rgMult(3) = DEVICE_INCOMPLETECOMMAND
    rgMult(4) = DEVICE_YESNOTEXT
    rgMult(5) = vbcrlf & trim(cl.DeviceVTYPrompt) & chr(32) & vbcrlf      
    rgMult(6) = "!# End of configuration file. Press Enter to continue."

   
    ' *NOTE: the device prompts need to be checked for last, as the WaitForMultData() exits on finding the first matching rgMult.
    ' We therefore need to check the output for all the errors or other possible responses first before the device prompts as a
    ' device prompt will nearly always occur at the end of the device response, whether the response is the expected output or
    ' an error or invalid command type message.
    rgMult(8) = cl.DeviceVTYPrompt
    rgMult(9) = cl.DeviceEnablePrompt
    rgMult(10) = cl.DeviceConfigPrompt
    
    ' Clear the response buffer
    cl.FlushRxBuffer
   
    ' Check if we are sending a Chr(26) command (i.e. Ctrl-Z)
    If sCmd = Chr(26) Or cl.WaitForEcho = False Then ' do not do a wait for echo of Ctrl-Z command, as we are sending to the device Chr(26) and device echos ^Z which will cause the SendAndWaitForEcho function to report a failure
        cl.SendData sCmd
    Else ' Send the command to the device and wait for an echo back of the command
        If cl.SendAndWaitForEcho(sCmd) = False Then ' Echo not received
            cl.Log 4, "Did not receive echo of " & sCmd
            Exit Function
        End If
    End If
   
    ' Make final timeout value adjustments for specific commands that take longer to complete sending back the output data
    ' By default the timeout is preset at 30 seconds.
    ' Examples:
    'If LCase(Left(sCmd, 9)) = "show tech" Then iTimeoutMultiplier = 5
    'If LCase(Left(sCmd, 14)) = "show interface" Then iTimeoutMultiplier = 3

    ' Send a message to Info Log pane showing timeout is being increased
    If iTimeoutMultiplier > 1 Then
        cl.Log 4, "Increasing timeout for next command only"
    End If
       
    ' Clear out response buffer again to remove any previous captured data text (i.e. the command text sent) if bCleanBuffer input parameter is set to True
    If bCleanBuffer Then cl.FlushRxBuffer
   
    ' Now send <CR> to execute the command on the device
    cl.SendData vbCr
               
    ' Check the device response and process the results
    cl.Log 4, "Waiting for a response to: " & sCmd
    Do
        ' Wait for a response from the device
        iRetVal = cl.WaitForMultData(rgMult, , COMMAND_TIMEOUT * iTimeoutMultiplier)
       
        ' Store the response
        sStoredBuffer = sStoredBuffer & cl.RxBuffer
        ' Analyse the results
        Select Case iRetVal
        Case 0
            ' No valid data received
            If iErrorLevel > 0 Then
                cl.Log iErrorLevel, "Did not receive expected response to command: " & sCmd
            End If
            Exit Do
        Case 1
            ' Handle the --more-- paging prompt.  Send space to advance to next page
            cl.FlushRxBuffer
            cl.SendData " "
        Case 2
            ' Invalid command - error with syntax
            If iErrorLevel > 0 Then
                cl.Log iErrorLevel, "Error with syntax: " & sCmd
            End If
            Exit Do
        Case 3
            ' Incomplete command
            If iErrorLevel > 0 Then
                cl.Log iErrorLevel, "Error with command: " & sCmd
            End If
            Exit Do
        Case 4
            ' yes/no (y/n) prompt
            cl.Log 4, "Y/N encountered"
            cl.FlushRxBuffer
            ' Send 'y' or 'n' depending on bYesToConfirm input parameter value
            If bYesToConfirm Then
                cl.Log 4, "Sending Y"
                cl.SendData "y" & vbCr
            Else
                cl.Log 4, "Sending N"
                cl.SendData "n" & vbCr
            End If
        Case 5
            'do nothing - ignore undesired echoed hostname prompt found at top of script (do not exit the loop)
            cl.Log 4, "Ignoring initial hostname prompt"
            cl.FlushRxBuffer
        Case 6
            cl.Log 4, "End of Config file detected"
            cl.FlushRxBuffer
            cl.SendData vbCr
        Case 8, 9, 10
            ' Command executed successfully and device prompt received back.  Set the function return value
            bCommandExecutedOK = True
           
            ' Massage data before returning, if requested
            If bCleanBuffer Then
                ' Trim off device prompt from end of response data if bCleanBuffer input parameter setto True
                sStart = InStrRev(sStoredBuffer, rgMult(iRetVal))
                If sStart > 0 Then sStoredBuffer = Mid(sStoredBuffer, 1, sStart - 1)
            End If
            Exit Do
        End Select
    Loop
   
    ' Final massage of response data before returning to CatTools
    If Len(DEVICE_MORETEXT) > 0 Then  ' Remove any --more-- paging prompts
        ' Use this next line to remove the whole line of output
        'sStoredBuffer = cl.TextRemoveLinesContainingText(sStoredBuffer, DEVICE_MORETEXT)
        ' ...or use this to replace the just the matching text within the line
        'sStoredBuffer = cl.ReplaceText(sStoredBuffer, DEVICE_MORETEXT, "")
    End If
   
    ' Return the data and send function return value
    cl.RxBuffer = sStoredBuffer
    SendCommandSingle = bCommandExecutedOK

End Function


Function SendCommandsMultiple(sCmdList, sCapturedDataFile, bYesToConfirm, bStopOnErrors, iNumCommands, iNumSuccess, iNumErrors)
' The Function SendCommandsMultiple() sends a series of commands (sCmdList) to the device and returns True if ALL commands
' were executed successfully, False if not.
' It also passes back information through the three returned iNum variables:
'
'   iNumCommands:   Used to return to the calling function the number of commands executed in total
'   iNumSuccess:    Used to return to the calling function the number of commands succesfully executed
'   iNumErrors:     Used to return to the calling function the number of commands unsuccesfully executed
'
' Calls On:         SendCommandSingle
'
' Date Created:     [AutoGenDateScriptCreated]
' Modifications:    (Date - Description of changes)
   
    ' Declare variables
    Dim iRetVal
    Dim rgCommandList
    Dim sCmd
    Dim iCount ' loop counter
    Dim sClientResultsFile
   
    ' Default function return value
    SendCommandsMultiple = True
   
    ' Set environment variables
    sCmd = ""
    iNumCommands = 0
    iNumSuccess = 0
    iNumErrors = 0
    iCount = 0
   
    ' Evaluate the commands
    rgCommandList = Split(sCmdList, vbCrLf)
    iNumCommands = UBound(rgCommandList)
    If iNumCommands = -1 Then Exit Function
   
    ' Send the commands
    Do
        sCmd = rgCommandList(iCount)

        ' Check whether command to send is a database Meta command, in which case do not send to device
        iRetVal = cl.DBMetaCmd(sCmd)
       
        If iRetVal = 0 Then
        ' Command is not a database Meta command so check whether command is a utility Meta command, in which case do not send to device
            iRetVal = cl.UtilityMetaCmd(sCmd)
        End If

       
        Select Case iRetVal
        Case 0 ' Not a meta command so send command to device and check if successful
            If SendCommandSingle(sCmd, bYesToConfirm, 2, False) Then
                iNumSuccess = iNumSuccess + 1
                ' Store output if required
                If Len(sCapturedDataFile) > 0 Then
                    cl.LogToFile sCapturedDataFile, cl.RxBuffer, 1
                   
'<*** The next block of code will only run with CatTools versions later than v3.2.19.  Do not uncomment if running 3.2.19 or prior as this will cause an error.
'                    ' Check the activity to see if the output of the command(s) should be emailed
'                    If cl.DBCheckScheduleOption(cl.ScheduleNumber, 😎 = 1 Then
'                       ' Write the output to a temporary file in the ClientTemp folder
'                        sClientResultsFile = cl.GetUniqueDeviceFileName("", "CLI")
'                        cl.LogToFile sClientResultsFile, cl.RxBuffer, 1
'                    End If
'***>
                End If
                ' Clear the response buffer ready for the next command
                cl.FlushRxBuffer
            Else ' Command not executed successfully
                iNumErrors = iNumErrors + 1
            End If
        Case 1
            ' Command to send is a Meta command and processed ok
            iNumSuccess = iNumSuccess + 1
        Case -1
            ' Command is a Meta command and error occurred
            iNumErrors = iNumErrors + 1
        End Select
       
        ' Check for errors and abort if necessary
        If iNumErrors > 0 And bStopOnErrors = 1 Then
            cl.Log 1, "Aborting command entry due to command error"
            SendCommandsMultiple = False
            Exit Do
        End If
        ' Increment counter to send next command
        iCount = iCount + 1
       
    Loop Until iCount > iNumCommands
    iNumCommands = iNumCommands + 1
   

End Function


Function Activity_BackupRunningConfig(sAltCommand, sTempFile, sIgnoreText)
' The Function Activity_BackupRunningConfig() is the activity used to get the running configuration from the device.
' It calls the GetConfig() function to capture the configuration data, sets the text to ignore in the configuration when comparing
' to the last configuration backup file, and passes the capture and ignore text back to the main activity script in CatTools.
'
' Calls On:         GetConfig
'
' Date Created:     [AutoGenDateScriptCreated]
' Modifications:    (Date - Description of changes)
    
   
    ' Declcare
    Dim sCmd
    Dim sStoredConfig
    Dim rgIgnoreText() ' ignore text array
   
   
    If Len(sAltCommand) > 0 Then
        sCmd = sAltCommand
    Else
        sCmd = COMMAND_RUNNINGCONFIG
    End If

    Activity_BackupRunningConfig = GetConfig(sCmd, sStoredConfig)

    ' Set the configuration lines (or text within a line) that should be ignored by the compare process
    sIgnoreText = ""
   
    ReDim rgIgnoreText(3) ' ReDeclare the array with 4 elements (*NOTE: arrays are 0 based).  Increment if more ignore text elements are added
    rgIgnoreText(0) = "^" & "! last configuration change at"
    rgIgnoreText(1) = "^" & "! nvram config last updated at"
    rgIgnoreText(2) = "^" & "ntp clock-period"
    rgIgnoreText(3) = "<" & "! No configuration change since last restart"
    'rgIgnoreText(4) = "...add an instruction here" & "... and ignore text here"
    
    'Ignore instructions define the context of the ignore text.
    '   ^ is the instruction to ignore lines with the sample text occurring anywhere in them
    '   < is the instruction to ignore lines that begin with the sample text
    '   > is the instruction to ignore lines that end with the sample text
   
    ' Join the above ignore text array elements
    sIgnoreText = Join(rgIgnoreText, "|")

    cl.LogToFile sTempFile, sStoredConfig, 0
       
End Function


Function Activity_SendCommands(sCommandsToSend, sCapturedDataFile, bYesToConfirm, bStopOnErrors)
' The Function Activity_SendCommands() is called by the Device.CLI.Send commands main script to send one or a group of user defined commands to a device.
' It also passes back information through the three returned iNum variables:
'
'   iNumCommands:   Used to return the number of commands executed in total
'   iNumSuccess:    Used to return the number of commands succesfully executed
'   iNumErrors:     Used to return the number of commands unsuccesfully executed
'
' Calls On:         SendCommandsMultiple
'
' Date Created:     [AutoGenDateScriptCreated]
' Modifications:    (Date - Description of changes)
       
   
    ' Declare variables
    Dim iNumCommands
    Dim iNumSuccess
    Dim iNumErrors
   
    ' Default function return value
    Activity_SendCommands = ""

    ' Call on the function which sends each command separately and report on the success or failure ofthe command
    SendCommandsMultiple sCommandsToSend, sCapturedDataFile, bYesToConfirm, bStopOnErrors, iNumCommands, iNumSuccess, iNumErrors

    ' Update function return value with the commands execution outcome
    Activity_SendCommands = iNumSuccess & " of " & iNumCommands & vbTab & iNumErrors

End Function


Function Activity_ModifyConfig(sCommandsToSend, sCapturedDataFile, bYesToConfirm, bStopOnErrors, bDoSaveToNVRAM)
' The Function Activity_ModifyConfig() is called by the Device.CLI.Modify config main script to send one or a group of user defined commands to a device.
' The difference to Activity_SendCommands is that it enters config mode first and then has the ability to save changes to startup config when finished.
' It also passes back information through the three returned iNum variables:
'
'   iNumCommands:   Used to return the number of commands executed in total
'   iNumSuccess:    Used to return the number of commands succesfully executed
'   iNumErrors:     Used to return the number of commands unsuccesfully executed
'
' Calls On:         SendCommandsMultiple
'
' Date Created:     [AutoGenDateScriptCreated]
' Modifications:    (Date - Description of changes)
   
    ' Declare variables
    Dim iNumCommands
    Dim iNumSuccess
    Dim iNumErrors
    Dim bContinueWithSave ' flag to save configuration changes
    Dim sSaveResults
    Dim sCmd
   
    ' Default function return value and variables
    Activity_ModifyConfig = ""
    bContinueWithSave = True
   
    ' Call function to enter config mode
    If EnterConfigMode = False Then Exit Function
   
    ' Send the commands. Stop if a 'stop-on-error' was triggered
    If Not SendCommandsMultiple(sCommandsToSend, sCapturedDataFile, bYesToConfirm, bStopOnErrors, iNumCommands, iNumSuccess, iNumErrors) Then
        ' Reset the configuration change flag
        bContinueWithSave = False
    End If
   
    ' Set the command to exit config
    sCmd = COMMAND_EXITCONFIG
    If LCase(sCmd) = "ctrl-z" Then
        sCmd = Chr(26)
    End If
   
    ' Send command to exit config mode
    cl.SendData sCmd
    cl.Log 4, "Exiting config mode"
    ' Wait for confirmation of exiting config mode
    If cl.WaitForData(cl.DeviceEnablePrompt, COMMAND_TIMEOUT) = False Then
       cl.Log 1, "Failed to exit config mode"
       Exit Function
    End If

    ' Save to Startup if option selected in activity
    If bDoSaveToNVRAM Then
        ' Double check that no errors occurred when sending the commands
        If bContinueWithSave Then
            ' No errors, so call function to save the changes to startup configuration
            sSaveResults = SaveToNVRAM
        Else ' command execution error occurred
            cl.Log 2, "Copy running to startup skipped because StopOnError was selected"
        End If
    Else
        sSaveResults = "N/A"
    End If
  

    ' Update function return value with the commands execution outcome and results
    Activity_ModifyConfig = iNumSuccess & " of " & iNumCommands & vbTab & iNumErrors & vbTab & sSaveResults

End Function


Function SaveToNVRAM()
' The Function SaveToNVRAM() is called by Activity_ModifyConfig function if the activity option
' to save the running configuration changes to start-up config is selected.
'
' Calls On:         N/A
'
' Date Created:     [AutoGenDateScriptCreated]
' Modifications:    (Date - Description of changes)
   
   
    ' Declare variables
    Dim iRetVal
   
    If Len(COMMAND_SAVENVRAM) = 0 Then
        SaveToNVRAM = "Skipped"
    Else
        ' Make sure we are not still in config mode when attempting save
        ExitConfigMode
       
        ' Confirm we are at the Enable prompt before doing save
        iRetVal = CurrentDeviceContextLevel
        ' 1 = VTY prompt, 2 = Enable prompt, 3 = Config prompt
       
        If iRetVal = 2 Then
            cl.Log 4, "Saving running-config to startup-config"
            ' Send the command
            If SendCommandSingle(COMMAND_SAVENVRAM, 1, 1, 0) = False Then
                ' Command failed
                SaveToNVRAM = "Failed"
            Else ' Command OK
                SaveToNVRAM = "OK"
            End If
           
        Else  ' Not at an Enable prompt
            SaveToNVRAM = "Cannot save to NVRAM as not currently in Enable mode"
        End If
   
    End If
   
End Function


Function Activity_InterDevicePing(sIPAddress)
    Call cl.CatToolsNoSupport
End Function

Function Activity_TFTPUpload(iActionType, sTFTPServer, sTFTPFile, sResponseFile, bDoSaveToNVRAM)
    Call cl.CatToolsNoSupport
    Activity_TFTPUpload = "Not supported"
End Function

Function Activity_UpdatePassword()
    Call cl.CatToolsNoSupport
End Function

Function Activity_Report_ARPTable(sAltCommand)
    Call cl.CatToolsNoSupport
End Function

Function Activity_Report_MACAddressTable(sAltCommand)
    Call cl.CatToolsNoSupport
End Function

Function Activity_Report_PortInfoTable(sAltCommand)
    Call cl.CatToolsNoSupport
End Function

Function Activity_Report_VersionTable(sAltCommand)
    Call cl.CatToolsNoSupport
End Function

Function Activity_Report_CDPNeighborsTable(sAltCommand, bHideDuplicateIP)
    Call cl.CatToolsNoSupport
End Function

Function Activity_Report_ErrorInfoTable()
    Call cl.CatToolsNoSupport
End Function

Function Activity_UpdateBanner(iBannerType, sDelimiter, sBannerText, sResponseFile, bDoSaveToNVRAM)
    Call cl.CatToolsNoSupport
    Activity_UpdateBanner = "Not supported"
End Function

Function Activity_Report_Compare_RunningStartup(sAltStartupCommand, sClientStartupFile, sAltRunningCommand, sClientRunningFile)
    Call cl.CatToolsNoSupport
End Function

 

 

0 Kudos

Hi Toosober,

You could post the script and ini in a zip file on the thwack content exchange in the Kiwi CatTools custom device script section.

With respect to the time stamp you should be able to get around this by using ignore text. In the Function 'Activity_BackupRunningConfig' function there is a section as outlined below and you should be able to add your own ignore text. You will need to redimension the array if you add additional items or replace the existing ignore text items with ones specific to your output;

    ' Set the configuration lines (or text within a line) that should be ignored by the compare process
    sIgnoreText = ""
   
    ReDim rgIgnoreText(3) ' ReDeclare the array with 4 elements (*NOTE: arrays are 0 based).  Increment if more ignore text elements are added
    rgIgnoreText(0) = "^" & "! last configuration change at"
    rgIgnoreText(1) = "^" & "! nvram config last updated at"
    rgIgnoreText(2) = "^" & "ntp clock-period"
    rgIgnoreText(3) = "<" & "! No configuration change since last restart"
    'rgIgnoreText(4) = "...add an instruction here" & "... and ignore text here"
    
    'Ignore instructions define the context of the ignore text.
    '   ^ is the instruction to ignore lines with the sample text occurring anywhere in them
    '   < is the instruction to ignore lines that begin with the sample text
    '   > is the instruction to ignore lines that end with the sample text
   
    ' Join the above ignore text array elements
    sIgnoreText = Join(rgIgnoreText, "|")

View solution in original post

0 Kudos

Thanks Wardini! Added the text at the beginning of the lines to rgIgnoreText( ) statements and it resolved the problem. I am now only getting "changed!" when there are actually changes. Also, I will post the zip file as you suggested, I am sure many other Avaya users will find it useful.

 

Thanks again for your post!

0 Kudos

No worries Toosober.

Thanks for sharing.

Kind regards,

Gareth

0 Kudos

No worries. Post back here if you need further assistance.

Kind regards,

Wardini

0 Kudos