Find value into array

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.

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

 

So you should read the information I linked above and maybe watch this video:

Sophisitcated Techniques of Plain Text Parsing

Or you could use an SNMP powershell module. I’ve used this one, but it only takes ip addresses: https://www.powershellgallery.com/packages/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.

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. :wink:
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

 

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?

Would it be unpolite when I say “That’s damn right.”? :wink:

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

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.

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!