Trying to create a script that will send a 'sh run | b interface' to a Cisco switch. Write the output to an array. Split that array with a vbcr so each line of the config is in a sep elemant of the array.
I have tried to skin the cat many ways and still I am struggling.
Logic in English: Send command to Cisco device Capture the output to an array define expected lines 'This are lines that are required under each 'interface' of the switch Match the 'interface' name and corresponding number and write it to a file. Check under that interface for the specific lines in the expected If it finds it, write the line & ", YES" If it does not find it, write the line & ", NO" Keep doing this until you do not find any more '^interface\s[FG][a-z].+'
Output should look like this: Interface GigabitEthernet 0/2 spanning-tree portfast, YES
This is the sample code that is failing:
'These are the expected line (not being compared in the script below but is my intention to have it compare the matched elements)
Dim vExpectedINT(4)
vExpectedINT(0) = "spanning-tree portfast"
vExpectedINT(1) = "switchport access vlan 17"
vExpectedINT(2) = "switchport mode access"
vExpectedINT(3) = "ip mtu 1400"
'objStream.Write "######################################################### " & vbcrlf
'objStream.Write "# I N T E R F A C E # " & vbcrlf
'objStream.Write "######################################################### " & vbcrlf
nCount = 0
vConfigLines = Split(strResultsINT, vbcr)
Set re = new RegExp
re.Global = False
re.IgnoreCase = True
re.Multiline = False
re.Pattern = "^interface [FG]"
' Regex Ex Definition
Set re2 = new RegExp
re2.Global = False
re2.IgnoreCase = True
re2.Multiline = False
re2.Pattern = "\sspanning-tree\sportfast"
' Regex Ex Definition
Set re3 = new RegExp
re3.Global = False
re3.IgnoreCase = True
re3.Multiline = False
re3.Pattern = "ip\smtu\s1400"
Set re4 = new RegExp
re4.Global = False
re4.IgnoreCase = True
re4.Multiline = False
re4.Pattern = "!"
' Compares the information
x = 1
Do While x <= Ubound(vConfigLines) - 1 do
MsgBox chr(34) & strLine & chr(34)
If re.Test(vConfigLines(x)) Then
' Write data to not expected section
x=x+1
do
If ! re4.Test(vConfigLines(x)) Then
MsgBox vConfigLines(x)
'objStream.Write vConfigLines(x) & vbcr
elseif re2.Test(vConfigLines(x)) Then
MsgBox vConfigLines(x)
elseif re3.Test(vConfigLines(x)) Then
MsgBox vConfigLines(x)
else
exit do
end if
x=x+1
loop
end IF
End If
Loop
This is a sample of the vConfigLines output:
There could be 48+ port per switch.
interface FastEthernet1/0/1
switchport access vlan 127
switchport mode access
switchport voice vlan 210
srr-queue bandwidth share 10 10 60 20
srr-queue bandwidth shape 0 3 0 0
priority-queue out
mls qos trust cos
auto qos voip trust
spanning-tree portfast
!
interface FastEthernet1/0/2
switchport access vlan 127
switchport mode access
switchport voice vlan 210
srr-queue bandwidth share 10 10 60 20
srr-queue bandwidth shape 0 3 0 0
priority-queue out
mls qos trust cos
auto qos voip trust
spanning-tree portfast
!
interface FastEthernet1/0/3
switchport access vlan 127
switchport mode access
switchport voice vlan 210
srr-queue bandwidth share 10 10 60 20
srr-queue bandwidth shape 0 3 0 0
priority-queue out
mls qos trust cos
auto qos voip trust
spanning-tree portfast
When facing a difficult and complex task, just follow these rules:
Divide the task in independently solvable subproblems
getting the info from Cisco
processing the resulting file
gather interesting info
output
Concentrate on the difficult subtask(s)
processing the resulting file
Solve a simplified but generalized version of (each) subtask using handmade data
for easy testing
You have items and are interested in whether they (don't) have given properties
Data to play with:
Item 0 (both props)
prop_a
prop_b
!
Item 1 (just b)
prop_b
!
Item 2 (a only)
prop_a
!
Item 3 (none)
!
Item 4 (irrelevant prop)
prop_c
!
Item 5 (Richy)
prop_c
prop_b
prop_a
!
Item 6 (Junky)
junk
prop_b
whatever
!
#Item 7 (Nasty)
# prop_a_like_but_not_prop_a
# prop_b
#!
Keep it simple
don't do more than absolutely necessary
don't use variables/components you can do without
So let's start:
You have to deal with a text file (lines). So don't do more than
Dim tsIn : Set tsIn = goFS.OpenTextFile("..\data\TheProblem.txt")
Dim sLine
Do Until tsIn.AtEndOfStream
sLine = Trim(tsIn.ReadLine())
If "" <> sLine Then
End If
Loop
tsIn.Close
90 % of the code using Split on .ReadAll is just fat. Yes, it's Do Until tsIn.AtEndOfStream
and not Do While tsIn.AtEndOfStream = False
. No Set tsIn = Nothing
,
please.
The data is organized in blocks (Item n ... !), so make sure you recognize the parts and know what to do when finding them:
Dim tsIn : Set tsIn = goFS.OpenTextFile("..\data\TheProblem.txt")
Dim sItem : sItem = "Item"
Dim sEnd : sEnd = "!"
Dim sLine
Do Until tsIn.AtEndOfStream
sLine = Trim(tsIn.ReadLine())
If "" <> sLine Then
Select Case True
Case 1 = Instr(sLine, sItem)
WScript.Echo "Begin, note item (name)"
Case 1 = Instr(sLine, sEnd)
WScript.Echo "End, output info"
WScript.Echo "----------"
Case Else
WScript.Echo "Middle, gather info"
End Select
End If
Loop
tsIn.Close
output:
Begin, note item (name)
Middle, gather info
Middle, gather info
End, output info
----------
Begin, note item (name)
Middle, gather info
End, output info
----------
...
For each item the output should be:
name, property, yes|no
The easiest way to do that is
WScript.Echo Join(aData, ", ")
Joining beats concatenation, especially if you want to set/manipulate the parts independently and/or to pre-set some of them in the beginning.
Dim aData : aData = Array( _
Array( "Item?", "prop_a", "NO") _
, Array( "Item?", "prop_b", "NO") _
)
Dim sLine, aTmp, nIdx
Do Until tsIn.AtEndOfStream
sLine = Trim(tsIn.ReadLine())
If "" <> sLine Then
Select Case True
Case 1 = Instr(sLine, sItem)
aTmp = aData
For nIdx = 0 To UBound(aTmp)
aTmp(nIdx)(0) = sLine
Next
Case 1 = Instr(sLine, sEnd)
For nIdx = 0 To UBound(aTmp)
WScript.Echo Join(aTmp(nIdx), ", ")
Next
WScript.Echo "----------"
Case Else
WScript.Echo "Middle, gather info"
End Select
End If
Loop
tsIn.Close
The output
...
Item 3 (none), prop_a, NO
Item 3 (none), prop_b, NO
...
shows that by setting sensible defaults (NO), this version of the script deals correctly with items having none of the interesting properties.
So lets tackle the middle/Case Else part:
Case Else
For nIdx = 0 To UBound(aTmp)
If 1 = Instr(sLine, aTmp(nIdx)(1)) Then
aTmp(nIdx)(2) = "YES"
Exit For
End If
Next
output now:
Item 0 (both props), prop_a, YES
Item 0 (both props), prop_b, YES
----------
Item 1 (just b), prop_a, NO
Item 1 (just b), prop_b, YES
----------
Item 2 (a only), prop_a, YES
Item 2 (a only), prop_b, NO
----------
Item 3 (none), prop_a, NO
Item 3 (none), prop_b, NO
----------
Item 4 (irrelevant prop), prop_a, NO
Item 4 (irrelevant prop), prop_b, NO
----------
Item 5 (Richy), prop_a, YES
Item 5 (Richy), prop_b, YES
----------
Item 6 (Junky), prop_a, NO
Item 6 (Junky), prop_b, YES
----------
But what about Nasty:
#Item 7 (Nasty)
# prop_a_like_but_not_prop_a
# prop_b
#!
The simple Instr() will fail, if one property name is a prefix of another. To prove that starting simple and add complexity later is good strategy:
Dim sFSpec : sFSpec = "..\data\TheProblem.txt"
WScript.Echo goFS.OpenTextFile(sFSpec).ReadAll
Dim tsIn : Set tsIn = goFS.OpenTextFile(sFSpec)
Dim sItem : sItem = "Item"
Dim sEnd : sEnd = "!"
Dim aData : aData = Array( _
Array( "Item?", "prop_a", "NO") _
, Array( "Item?", "prop_b", "NO") _
)
Dim aRe : aRe = Array(New RegExp, New RegExp)
Dim nIdx
For nIdx = 0 To UBound(aRe)
aRe(nIdx).Pattern = "^" & aData(nIdx)(1) & "$"
Next
Dim sLine, aTmp
Do Until tsIn.AtEndOfStream
sLine = Trim(tsIn.ReadLine())
If "" <> sLine Then
Select Case True
Case 1 = Instr(sLine, sItem)
aTmp = aData
For nIdx = 0 To UBound(aTmp)
aTmp(nIdx)(0) = sLine
Next
Case 1 = Instr(sLine, sEnd)
For nIdx = 0 To UBound(aTmp)
WScript.Echo Join(aTmp(nIdx), ", ")
Next
WScript.Echo "----------"
Case Else
For nIdx = 0 To UBound(aTmp)
If aRe(nIdx).Test(sLine) Then
aTmp(nIdx)(2) = "YES"
Exit For
End If
Next
End Select
End If
Loop
tsIn.Close
output:
Item 0 (both props)
prop_a
prop_b
!
Item 1 (just b)
prop_b
!
Item 2 (a only)
prop_a
!
Item 3 (none)
!
Item 4 (irrelevant prop)
prop_c
!
Item 5 (Richy)
prop_c
prop_b
prop_a
!
Item 6 (Junky)
junk
prop_b
whatever
!
Item 7 (Nasty)
prop_a_like_but_not_prop_a
prop_b
!
Item 0 (both props), prop_a, YES
Item 0 (both props), prop_b, YES
----------
Item 1 (just b), prop_a, NO
Item 1 (just b), prop_b, YES
----------
Item 2 (a only), prop_a, YES
Item 2 (a only), prop_b, NO
----------
Item 3 (none), prop_a, NO
Item 3 (none), prop_b, NO
----------
Item 4 (irrelevant prop), prop_a, NO
Item 4 (irrelevant prop), prop_b, NO
----------
Item 5 (Richy), prop_a, YES
Item 5 (Richy), prop_b, YES
----------
Item 6 (Junky), prop_a, NO
Item 6 (Junky), prop_b, YES
----------
Item 7 (Nasty), prop_a, NO
Item 7 (Nasty), prop_b, YES
----------