Find value into array

Welcome Forums General PowerShell Q&A Find value into array

Viewing 18 reply threads
  • Author
    Posts
    • #234796
      Participant
      Topics: 13
      Replies: 46
      Points: 65
      Rank: Member

      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.

    • #234799
      Participant
      Topics: 5
      Replies: 2373
      Points: 6,011
      Helping Hand
      Rank: Community MVP

      What have you tried so far? Please, along with the sample data you should post your code. I’d recommend to use regular expressions.

    • #234811
      Participant
      Topics: 13
      Replies: 46
      Points: 65
      Rank: Member

      What have you tried so far? Please, along with the sample data you should post your code. I’d recommend to use regular expressions.

      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

       

    • #234814
      Participant
      Topics: 5
      Replies: 2373
      Points: 6,011
      Helping Hand
      Rank: Community MVP

      The need is that based on a string (ie: 40GE0 / 0/1) …

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

      Sophisitcated Techniques of Plain Text Parsing

    • #234835
      js
      Participant
      Topics: 30
      Replies: 828
      Points: 2,556
      Helping Hand
      Rank: Community Hero

      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

    • #235186
      Participant
      Topics: 13
      Replies: 46
      Points: 65
      Rank: Member

      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.

    • #235192
      Participant
      Topics: 5
      Replies: 2373
      Points: 6,011
      Helping Hand
      Rank: Community MVP

      Now I need to find data from an array based on a value from the other.

      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.

    • #235195
      Participant
      Topics: 13
      Replies: 46
      Points: 65
      Rank: Member

      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

       

      • This reply was modified 3 weeks, 6 days ago by Rodrigo.
      • This reply was modified 3 weeks, 6 days ago by Rodrigo.
    • #235270
      Participant
      Topics: 5
      Replies: 2373
      Points: 6,011
      Helping Hand
      Rank: Community MVP

      Below the complete code:

      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?

    • #235294
      Participant
      Topics: 13
      Replies: 46
      Points: 65
      Rank: Member

      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.

    • #235297
      Participant
      Topics: 13
      Replies: 46
      Points: 65
      Rank: Member

      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?

    • #235309
      Participant
      Topics: 5
      Replies: 2373
      Points: 6,011
      Helping Hand
      Rank: Community MVP

      I don’t think I was very clear about the need.

      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.

    • #235318
      Participant
      Topics: 13
      Replies: 46
      Points: 65
      Rank: Member

      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.

    • #235324
      Participant
      Topics: 0
      Replies: 3
      Points: 3
      Rank: Member

      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
      • This reply was modified 3 weeks, 5 days ago by p0rkjello.
    • #235327
      Participant
      Topics: 5
      Replies: 2373
      Points: 6,011
      Helping Hand
      Rank: Community MVP

      But, the data is not in a table or a text file, is result of a snmpwalk request.

      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
      }
      
      • #235336
        Participant
        Topics: 13
        Replies: 46
        Points: 65
        Rank: Member

        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.

    • #235348
      js
      Participant
      Topics: 30
      Replies: 828
      Points: 2,556
      Helping Hand
      Rank: Community Hero

      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
      • This reply was modified 3 weeks, 5 days ago by js.
    • #235354
      Participant
      Topics: 13
      Replies: 46
      Points: 65
      Rank: Member

      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. 

      • This reply was modified 3 weeks, 5 days ago by Rodrigo.
    • #235405
      Participant
      Topics: 13
      Replies: 46
      Points: 65
      Rank: Member

      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
    • #235411
      Participant
      Topics: 13
      Replies: 46
      Points: 65
      Rank: Member

      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!

Viewing 18 reply threads
  • You must be logged in to reply to this topic.