skip to Main Content

We are trying to Pull AP names and two specific Bssid values out of json files provided by network team, in PowerShell 5.1

Started with the following function to get the names (this works for just the names), but am stumped on how to get ChildItems, or if it’s even possible to pull child items when searching a string like this, unlikely would be my guess.

Function GetName {
$WapName = get-content $FileName -Raw |
    Select-String -pattern '"name":s*"?([^",]+)"?,?' -allmatches |  
        Foreach-Object { $_.Matches | ##Get-childItem matching specific ESSID, return macaddr ??
            Foreach-Object { $_.Groups[1].Value}
        }

    if ($null -eq $WapName){
        Write-Host "Array is null"
       }# End of If
    else{
        Write-Host "Array has $($WapName.length) elements"
        $WapName
       }#End of Else

}#End of Function

Thinking we may need to convertFrom-Json to achieve child item pulls, but am unfamiliar with how to work with that data. want to Ultimately get this converted to a csv file for manipulation.

Here’s example of JSON file. We need AP Names and each associated wifi macaddr value for the wifitrusted and wifiguest items only. The rest of the data is unneeded.

{
  "aps": [
    {
      "macaddr": "xx:xx:xx:xx:xx:xx",
      "name": "**WAP01**",
      "radio_bssids": [
        {
          "bssids": [
            {
              "essid": "wifiguest",
              "macaddr": "**xx:xx:xx:xx:xx:xx**"
            },
            {
              "essid": "wifitrusted",
              "macaddr": "**xx:xx:xx:xx:xx:xx**"
            },
            {
              "essid": "Wifi-xyz",
              "macaddr": "xx:xx:xx:xx:xx:xx"
            }
          ],
          "index": 0,
          "macaddr": "xx:xx:xx:xx:xx:xx"
        },
        {
          "bssids": [
            {
              "essid": "wifiguest",
              "macaddr": "**xx:xx:xx:xx:xx:xx**"
            },
            {
              "essid": "wifitrusted",
              "macaddr": "**xx:xx:xx:xx:xx:xx**"
            },
            {
              "essid": "Wifi-xyz",
              "macaddr": "xx:xx:xx:xx:xx:xx"
            }
          ],
          "index": 1,
          "macaddr": "xx:xx:xx:xx:xx:xx"
        }
      ],
      "serial": "sjfdgkjafdgl",
      "swarm_id": "kjslkfdjgaofdsgj0w94rlkjo9wrjliwedlkfjwo3"
    },
    {
      "macaddr": "xx:xx:xx:xx:xx:xx",
      "name": "**WAP02**",
      "radio_bssids": [
        {
          "bssids": [
            {
              "essid": "wifiguest",
              "macaddr": "**xx:xx:xx:xx:xx:xx**"
            },
            {
              "essid": "wifitrusted",
              "macaddr": "**xx:xx:xx:xx:xx:xx**"
            },
            {
              "essid": "Wifi-xyz",
              "macaddr": "xx:xx:xx:xx:xx:xx"
            }
          ],
          "index": 0,
          "macaddr": "xx:xx:xx:xx:xx:xx"
        },
        {
          "bssids": [
            {
              "essid": "wifiguest",
              "macaddr": "**xx:xx:xx:xx:xx:xx**"
            },
            {
              "essid": "wifitrusted",
              "macaddr": "**xx:xx:xx:xx:xx:xx**"
            },
            {
              "essid": "Wifi-xyz",
              "macaddr": "xx:xx:xx:xx:xx:xx"
            }
          ],
          "index": 1,
          "macaddr": "xx:xx:xx:xx:xx:xx"
        }
      ],
      "serial": "lasjdhfad",
      "swarm_id": "lkasdjlkajsd;kasdfja;lsdkjffkjlkfj"
    },
  ],
  "count": 2
}

Preferred Output would be something like this repeated for each WAP with ALL records containing wifitrusted and wifiguest:

WAP ESSID   MACAddr
WAP01   wifitrusted xx:xx:xx:xx:xx:xx
WAP02   wifiguest   xx:xx:xx:xx:xx:xx

Thanks for the assist.

Tried going this route in an attempt to get wifiguest to return, this is broken and just a placeholder at this point really as it is not fully what is needed. We are importing the json file into parameter $FileName.

Function GetEssid {
$ESSID = [ordered]@{}
$ESSID = (get-content $FileName -Raw | Convertfrom-Json).PSobject.Properties |
ForEach-Object {$ESSID[$_.essid] = $_.Value }

$ESSID.Stuffs.Where({$_.essid -eq "wifiguest"}).Value

2

Answers


  1. Presumably something like this should help, it’s unclear if you just want 2 records as-in your sample or just all records where ESSID is wifiguest or wifitrusted but this should be a start.

    $json = Get-Content $FileName -Raw | ConvertFrom-Json
    $json.aps | ForEach-Object {
        foreach ($item in $_.radio_bssids) {
            foreach ($bssid in $item.bssids) {
                if ($bssid.essid -in 'wifiguest', 'wifitrusted') {
                    [pscustomobject]@{
                        WAP     = $_.name
                        ESSID   = $bssid.essid
                        MACAddr = $bssid.macaddr
                        Index   = $item.index
                    }
                }
            }
        }
    }
    

    Using the sample Json provided in question the output from the above is:

    WAP       ESSID       MACAddr               Index
    ---       -----       -------               -----
    **WAP01** wifiguest   **xx:xx:xx:xx:xx:xx**     0
    **WAP01** wifitrusted **xx:xx:xx:xx:xx:xx**     0
    **WAP01** wifiguest   **xx:xx:xx:xx:xx:xx**     1
    **WAP01** wifitrusted **xx:xx:xx:xx:xx:xx**     1
    **WAP02** wifiguest   **xx:xx:xx:xx:xx:xx**     0
    **WAP02** wifitrusted **xx:xx:xx:xx:xx:xx**     0
    **WAP02** wifiguest   **xx:xx:xx:xx:xx:xx**     1
    **WAP02** wifitrusted **xx:xx:xx:xx:xx:xx**     1
    
    Login or Signup to reply.
  2. Continuing on the helpful answer from Santiago Squarzon with a general approach:
    Iterating through an object-graph resulted from cmdlets as ConvertFrom-Json appears to be a quiet common use-case in PowerShell. Therefore I have tagged several other examples with: powershell/object-graph

    In your case, it might come in handy to understand the path a of specific (leaf) node, e.g.:

    Install-Module -Name ObjectGraphTools
    
    $Data = Get-Content $FileName -Raw | ConvertFrom-Json
    $Data | Get-ChildNode -Recurse -Leaf
    
    Path                                     Name     Depth Value
    ----                                     ----     ----- -----
    aps[0].macaddr                           macaddr      3 xx:xx:xx:xx:xx:xx
    aps[0].name                              name         3 **WAP01**
    aps[0].radio_bssids[0].bssids[0].essid   essid        7 wifiguest
    aps[0].radio_bssids[0].bssids[0].macaddr macaddr      7 **xx:xx:xx:xx:xx:xx**
    ...
    

    This might help you to address the specific nodes.

    Using the included Extended Dot Notation expression you might even easier target specific nodes and avoid several embedded foreach loops.

    In the example below I am also using the standard PowerShell feature called calculated properties:

    $Data | Get-Node ~essid=wifiguest/wifitrusted | Select-Object (
        @{ Name = 'WAP';     Expression = { $_.GetNode('......Name').Value } },
        @{ Name = 'ESSID';   Expression = { $_.Value } },
        @{ Name = 'MACAddr'; Expression = { $_.GetNode('..macaddr').Value } },
        @{ Name = 'Index';   Expression = { $_.GetNode('....index').Value } }
    )
    
    WAP       ESSID       MACAddr               Index
    ---       -----       -------               -----
    **WAP01** wifiguest   **xx:xx:xx:xx:xx:xx**     0
    **WAP01** wifitrusted **xx:xx:xx:xx:xx:xx**     0
    **WAP01** wifiguest   **xx:xx:xx:xx:xx:xx**     1
    **WAP01** wifitrusted **xx:xx:xx:xx:xx:xx**     1
    **WAP02** wifiguest   **xx:xx:xx:xx:xx:xx**     0
    **WAP02** wifitrusted **xx:xx:xx:xx:xx:xx**     0
    **WAP02** wifiguest   **xx:xx:xx:xx:xx:xx**     1
    **WAP02** wifitrusted **xx:xx:xx:xx:xx:xx**     1
    

    Explanation:

    • ~ search for any leaf node named:
      • essid and a value of:
        • =wifiguest or:
        • /wifitrusted
      • (A full specific member access enumeration path as aps.radio_bssids.bssids.essid=wifiguest/wifitrusted could also be used here)
    • In the calculated expressions, node notations as e.g. ......Name mean: from the current node, go 5 parents up (a single dot –.– represents the current node) and select the child node named Name.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search