Hi guys, all right?
I have a need to find a value based on an array. However, I need to dynamically get an identifier. See the list below:
.1.3.6.1.2.1.47.1.1.1.1.7.67469966 = STRING: "XGigabitEthernet0 / 0/10"
.1.3.6.1.2.1.47.1.1.1.1.7.67470030 = STRING: "XGigabitEthernet0 / 0/11"
.1.3.6.1.2.1.47.1.1.1.1.7.67470094 = STRING: "XGigabitEthernet0 / 0/12"
.1.3.6.1.2.1.47.1.1.1.1.7.67470158 = STRING: "XGigabitEthernet0 / 0/13"
.1.3.6.1.2.1.47.1.1.1.1.7.67470222 = STRING: "XGigabitEthernet0 / 0/14"
.1.3.6.1.2.1.47.1.1.1.1.7.67470286 = STRING: "XGigabitEthernet0 / 0/15"
.1.3.6.1.2.1.47.1.1.1.1.7.67470350 = STRING: "XGigabitEthernet0 / 0/16"
.1.3.6.1.2.1.47.1.1.1.1.7.67470414 = STRING: "XGigabitEthernet0 / 0/17"
.1.3.6.1.2.1.47.1.1.1.1.7.67470478 = STRING: "XGigabitEthernet0 / 0/18"
.1.3.6.1.2.1.47.1.1.1.1.7.67470542 = STRING: "XGigabitEthernet0 / 0/19"
.1.3.6.1.2.1.47.1.1.1.1.7.67470606 = STRING: "XGigabitEthernet0 / 0/20"
.1.3.6.1.2.1.47.1.1.1.1.7.67470670 = STRING: "XGigabitEthernet0 / 0/21"
.1.3.6.1.2.1.47.1.1.1.1.7.67470734 = STRING: "XGigabitEthernet0 / 0/22"
.1.3.6.1.2.1.47.1.1.1.1.7.67470798 = STRING: "XGigabitEthernet0 / 0/23"
.1.3.6.1.2.1.47.1.1.1.1.7.67470862 = STRING: "XGigabitEthernet0 / 0/24"
.1.3.6.1.2.1.47.1.1.1.1.7.67485774 = STRING: "40GE0/0/1"
.1.3.6.1.2.1.47.1.1.1.1.7.67485838 = STRING: "40GE0/0/2"
The value I need to search for is: 40GE0 / 0/1. When he finds it, as below:
.1.3.6.1.2.1.47.1.1.1.1.7.67485774 = STRING: "40GE0/0/1"
The identifier I need is the value
67485774
Does anyone have any idea how they could do this?
I appreciate any help.
Olaf
June 10, 2020, 1:19pm
2
What have you tried so far? Please, along with the sample data you should post your code. I’d recommend to use regular expressions .
[quote quote=234799]What have you tried so far? Please, along with the sample data you should post your code. I’d recommend to use regular expressions .
[/quote]
We don’t have any code yet, just the SNMP query that returns the list of information. The need is that based on a string (ie: 40GE0 / 0/1) I need to get the code that is in a specific position in the query result.
Thank you for your reply
Olaf
June 10, 2020, 3:08pm
4
So you should read the information I linked above and maybe watch this video:
Sophisitcated Techniques of Plain Text Parsing
js2010
June 10, 2020, 4:15pm
5
Or you could use an SNMP powershell module. I’ve used this one, but it only takes ip addresses: PowerShell Gallery | SNMP 1.0.0.1
I made some progress. After fetching the data through the snmpwalk I can put the two information in two arrays. Now I need to find data from an array based on a value from the other. follow the code:
$ portid = $ getportid
$ portname = $ getportname
function Combine-Arrays ($ array1, $ array2, $ headers) {
for ($ index = 0; $ index -lt $ array1.Count; $ index ++) {
[PSCustomObject] @ {
$ headers [0] = $ array1 [$ index]
$ headers [1] = $ array2 [$ index]
}
}
}
$ headers = "PortID", "PortName"
Combine-Arrays $ portid $ portname $ headers
The result is:
67470414 XGigabitEthernet0 / 0/17
67470478 XGigabitEthernet0 / 0/18
67470542 XGigabitEthernet0 / 0/19
67470606 XGigabitEthernet0 / 0/20
67470670 XGigabitEthernet0 / 0/21
67470734 XGigabitEthernet0 / 0/22
67470798 XGigabitEthernet0 / 0/23
67470862 XGigabitEthernet0 / 0/24
67485774 40GE0 / 0/1
67485838 40GE0 / 0/2
68157445 Board slot 1
69206021 Board slot 2
70254597 Board slot 3
71303173 Board slot 4
72351749 Board slot 5
73400325 Board slot 6
74448901 Board slot 7
75497477 Board slot 8
when I look for the value
40GE0 / 0/1 I need to put the value
67485774 in a variable.
Again, I appreciate any help.
Olaf
June 11, 2020, 4:34pm
7
That’s actually a pretty easy task. But you should share some source data and maybe some examples of expected result - not the result you get now.
You may share the code you use to collect the soure data as well. There might be an easier way to do what you need.
BTW:
Your code is broken because of a lot of space charachters.
Hello Olaf, thank you for your reply,
Below the complete code:
$getportname = (snmpwalk.exe -Ln -On -v 2c -c public 10.1.1.1 "1.3.6.1.2.1.55.14.1.1.11.7")
$strnum = $strnum -replace '.*\"(.*?)\"\s*$','$1'
$getportid = $getportname.Substring(26,9)
$getportname = $getportname -replace '.*\"(.*?)\"\s*$','$1'
$portid= $getportid
$portname= $getportname
function Combine-Arrays($array1,$array2,$headers){
for($index=0;$index-lt$array1.Count;$index++){ [PSCustomObject] @{
$headers[0]=$array1[$index]
$headers[1]=$array2[$index]
}
}
}
$headers="PortID","PortName"
Combine-Arrays $portid $portname $headers
Olaf
June 11, 2020, 11:08pm
9
Hmmm … ok, that does not help in this case. Maybe this helps - let’s say you have some input data where you only get a kind of index number:
$inputData = @'
Number,RandomData,AnotherRandomData
69206021,blabla,1234567
67485838,blablu,89101112
70254597,blablo,131415
67485774,blabli,16171819
'@ |
ConvertFrom-Csv
Now you need to associate this index number with a friendly / human readable name. You can use a look-up table for this:
$lookupTable =
@{
'67485774' = '40GE0 / 0 / 1'
'67485838' = '40GE0 / 0 / 2'
'68157445' = 'Board slot 1'
'69206021' = 'Board slot 2'
'70254597' = 'Board slot 3'
}
Now it’s easy to combine this with each other:
foreach($item in $inputData){
[PSCustomObject]@{
Number = $item.Number
RandomData = $item.RandomData
FriendlyName = $lookupTable[$item.Number]
}
}
And that would be the result:
Number RandomData FriendlyName
------ ---------- ------------
69206021 blabla Board slot 2
67485838 blablu 40GE0 / 0 / 2
70254597 blablo Board slot 3
67485774 blabli 40GE0 / 0 / 1
Does this help?
Hi Olaf,
I don’t think I was very clear about the need. I will have a search box or a parameter that when I enter the term (in this case 40GE0 / 0/1) it brings me the number immediately to the left of the position where the term is.
Like that:
param (
[string] $ port = "40GE0/0/1"
)
When I find the value of
$ port I need the value on the left to be inserted into another variable. Type
$ portid It will always be one search at a time.
again, thank you very much for your support.
Perhaps an alternative is to take the value of the line and put it in the variable. like that:
param (findstr = "40GE0 / 0/1")
Scroll through the table and find:
$ data_located = 67485774 40GE0 / 0/1
So is it clear?
Olaf
June 12, 2020, 2:56am
12
Would it be unpolite when I say “That’s damn right.”?
Something like this could be a very basic version …
$lookupTable =
@{
'67470414' = 'XGigabitEthernet0 / 0 / 17'
'67470478' = 'XGigabitEthernet0 / 0 / 18'
'67470542' = 'XGigabitEthernet0 / 0 / 19'
'67470606' = 'XGigabitEthernet0 / 0 / 20'
'67470670' = 'XGigabitEthernet0 / 0 / 21'
'67470734' = 'XGigabitEthernet0 / 0 / 22'
'67470798' = 'XGigabitEthernet0 / 0 / 23'
'67470862' = 'XGigabitEthernet0 / 0 / 24'
'67485774' = '40GE0 / 0 / 1'
'67485838' = '40GE0 / 0 / 2'
'68157445' = 'Board slot 1'
'69206021' = 'Board slot 2'
'70254597' = 'Board slot 3'
'71303173' = 'Board slot 4'
'72351749' = 'Board slot 5'
'73400325' = 'Board slot 6'
'74448901' = 'Board slot 7'
'75497477' = 'Board slot 8'
}
while ($true) {
$userInput = Read-Host -Prompt 'Please enter a search pattern'
if ($userInput -eq 'x') {
break
}
$lookupTable.GetEnumerator() | Where-Object { $_.Value -match [REGEX]::Escape($userInput) }
}
… it’s enough to enter just a part of the searched string. So for example when you enter “20” you will get the 4th element of the look-up table.
Thats is almost we need…
But, the data is not in a table or a text file, is result of a snmpwalk request.
param(
[string]$port = "40GE0/0/1"
)
$getportname = (snmpwalk.exe -Ln -On -v 2c -c $community $hostip "1.3.6.1.2.1.2099.1.3.4.4.1.1.7")
$getportname
So, the result of request is:
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67470158 = STRING: "XGigabitEthernet0/0/13"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67470222 = STRING: "XGigabitEthernet0/0/14"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67470286 = STRING: "XGigabitEthernet0/0/15"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67470350 = STRING: "XGigabitEthernet0/0/16"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67470414 = STRING: "XGigabitEthernet0/0/17"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67470478 = STRING: "XGigabitEthernet0/0/18"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67470542 = STRING: "XGigabitEthernet0/0/19"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67470606 = STRING: "XGigabitEthernet0/0/20"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67470670 = STRING: "XGigabitEthernet0/0/21"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67470734 = STRING: "XGigabitEthernet0/0/22"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67470798 = STRING: "XGigabitEthernet0/0/23"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67470862 = STRING: "XGigabitEthernet0/0/24"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67485774 = STRING: "40GE0/0/1"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67485838 = STRING: "40GE0/0/2"
I adjust data for remove the OID information. With substring method.
67470158 = STRING: "XGigabitEthernet0/0/13"
67470222 = STRING: "XGigabitEthernet0/0/14"
67470286 = STRING: "XGigabitEthernet0/0/15"
67470350 = STRING: "XGigabitEthernet0/0/16"
67470414 = STRING: "XGigabitEthernet0/0/17"
67470478 = STRING: "XGigabitEthernet0/0/18"
67470542 = STRING: "XGigabitEthernet0/0/19"
67470606 = STRING: "XGigabitEthernet0/0/20"
67470670 = STRING: "XGigabitEthernet0/0/21"
67470734 = STRING: "XGigabitEthernet0/0/22"
67470798 = STRING: "XGigabitEthernet0/0/23"
67470862 = STRING: "XGigabitEthernet0/0/24"
67485774 = STRING: "40GE0/0/1"
67485838 = STRING: "40GE0/0/2"
Finely, when find the $port (40GE0/0/1, or other) show the line with data:
67485774 = STRING: "40GE0/0/1"
I hope that I have been a more clear now…in advance, my apologies for the confused informations.
If you are looking to get that 8 digit number from the results. For the last output example you posted, split the results into an array and select the 1st item.
❭ $Value = '67485774 = STRING: "40GE0/0/1"'
❭ $Value.Split('=').Trim()[0]
67485774
Olaf
June 12, 2020, 4:18am
15
So you have to parse it as needed … the code is actually the same …
$lookupTable = @'
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67470158 = STRING: "XGigabitEthernet0/0/13"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67470222 = STRING: "XGigabitEthernet0/0/14"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67470286 = STRING: "XGigabitEthernet0/0/15"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67470350 = STRING: "XGigabitEthernet0/0/16"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67470414 = STRING: "XGigabitEthernet0/0/17"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67470478 = STRING: "XGigabitEthernet0/0/18"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67470542 = STRING: "XGigabitEthernet0/0/19"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67470606 = STRING: "XGigabitEthernet0/0/20"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67470670 = STRING: "XGigabitEthernet0/0/21"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67470734 = STRING: "XGigabitEthernet0/0/22"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67470798 = STRING: "XGigabitEthernet0/0/23"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67470862 = STRING: "XGigabitEthernet0/0/24"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67485774 = STRING: "40GE0/0/1"
1.3.6.1.2.1.2099.1.3.4.4.1.1.7.67485838 = STRING: "40GE0/0/2 "
'@ -split "`n" |
ForEach-Object {
[PSCustomObject]@{
PortNumber = $_.substring(31,8)
PortName = $_.substring(51,$_.length - 53)
}
}
while ($true) {
$userInput = Read-Host -Prompt 'Please enter a search pattern for PortNumber'
if ($userInput -eq 'x') {
break
}
$lookupTable |
Where-Object { $_.PortName -match [REGEX]::Escape($userInput) } |
Out-Host
}
we are closer
In this code:
while ($ true) {
$ userInput = Read-Host -Prompt 'Enter a search pattern for PortNumber'
if ($ userInput -eq 'x') {
to break
}
$ lookupTable |
Where-object {$ _. PortName -match [REGEX] :: Escape ($ userInput)} |
Out-Host
}
Is it possible to place the string search based on a variable and not with the box search?
This is because the execution will be via script, like this:
powershell script_getport 10.1.1.1 40GE0 / 0/1
The return would be just the ID:
67485774
Only that.
js2010
June 12, 2020, 5:44am
17
Here’s an example of using the SNMP module from powershell gallery. No parsing required. This oid gets the printer model.
invoke-snmpwalk -ip 192.168.1.1 -OIDStart .1.3.6.1.2.1.25.3.2.1.3
OID Data
--- ----
.1.3.6.1.2.1.25.3.2.1.3.1 RICOH MP 6055
.1.3.6.1.2.1.25.3.2.1.3.2 RICOH MP 6055
.1.3.6.1.2.1.25.3.2.1.3.3 RICOH MP 6055
.1.3.6.1.2.1.25.3.2.1.3.5 RICOH MP 6055
I Made some adjustement on the code:
param(
[string]$hostip = "10.1.1.1",
[string]$community = "public",
[string]$port = "40GE0/0/1"
)
$getportname = (snmpwalk.exe -Ln -On -v 2c -c $community $hostip "1.3.6.1.2.1.2900.1.4.9.1.1")
$table = @($getportname)
$lookupTable = ($table) |
ForEach-Object {
[PSCustomObject]@{
PortNumber = $_.Substring(26,9)
PortName = $_ -replace '.*\"(.*?)\"\s*$','$1'
}
}
while ($true) {
$userInput = Read-Host -Prompt 'Please enter a search pattern for PortNumber'
if ($userInput -eq 'x') {
break
}
$lookupTable | Where-Object { $_.PortName -match [REGEX]::Escape($userInput) } | Out-Host
}
Running the code:
Please enter a search pattern for PortNumber: 40GE0/0/1
PortNumber PortName
---------- --------
67485774 40GE0/0/1
Now, we need to execute the code without putting the string in the search, but through the $port variable. And in the end, remove the headers and put PortNumber in a variable.
Thank you very much for the help.
I have changed the code to pass a search by variable
while ($true) {
$userInput = $port
if ($userInput -eq 'x') {
break
}
$lookupTable |
Where-Object { $_.PortName -match [REGEX]::escape($userInput) }
}
The result:
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
67485774 40GE0/0/1
Maybe is because of the
while
I solved it with the code below:
$ portid = for ($ i = 1; $ i -le 1; $ i ++) {
$ userInput = $ port
$ lookupTable |
Where-Object {$ _. PortName -match [REGEX] :: escape ($ userInput)} # |
# Out-Host
}
$ portid.PortNumber
Thank you for all help!