简体   繁体   中英

Looping through properties inside a PSObject in PowerShell (from json)

After opening a .json file in PowerShell, I've got a new PSObject called $json_sitesandsnets. Ultimately what I want to do is loop through each Site (Orlando, Denver), and loop through each of their subnets, and do stuff. Initially, I need to create these subnets for the corresponding Site in Active Directory with the New-ADReplicationSubnet cmdlet. I've already used this to create a single subnet, but I've got a much larger list of Sites & Subnets I'll be working with. This example is just a small trimmed down version to post here. Once I figure out how to access those subnets in the objects Value, I might just feed each subnet list to New-ADReplicationSubnet. But I really want to be able to loop through each subnet for other purposes. I'm thinking that this is probably not difficult to do, once you know how to do it.

Here is the raw json:

{
"Orlando":  [
                        "10.10.10.0/24",
                        "10.10.20.0/24",
                        "10.10.30.0/24",
                        "10.10.40.0/24"
                    ],
"Denver":  [
                       "10.0.70.0/24",
                       "10.0.80.0/24",
                       "10.0.90.0/24",
                       "10.0.100.0/24",
                       "10.0.110.0/24",
                       "10.0.120.0/24"
                   ]
}

And I get the PSObject's properties like this:

$json_sitesandsnets.psobject.properties

PSObject properties

When I run Debug in VSCode, I can see the PSObject and the list (array) of subnets: seeing this in Debug

Here is some code, which gets the Name no problem (Write-Host $site.Name). As you can see, I've tried a couple of different ways to access those subnets, which are the Value of each site. And I just cannot figure it out. I've read so many articles and forum threads about looping through PSObjects, but just can't seem to find the golden answer to accessing and looping through the array that is the Value of the PSObject. I feel like I'm really close.

foreach ($site in $json_sitesandsnets.PSObject.Properties) {
Write-Host $site.Name
$site| get-member -type NoteProperty | foreach-object {
    $subnet = $site."$($_.Value)"
    Write-Host $subnet
    Write-Host $_.Value
}
}

You can do this by using the site name to index. $json_sitesandsnets.($site.Name)

I would also use $json_sitesandsnets.PSObject.Properties.Name in the foreach instead of $json_sitesandsnets.PSObject.Properties , to simplify things:

foreach ($site in $json_sitesandsnets.PSObject.Properties.Name) {
    Write-Host $site
    foreach ($subnet in $json_sitesandsnets.$site){
        Write-Host "logic for subnet $subnet"
    }
    # alternatively
    $json_sitesandsnets.$site | ForEach-Object {
        Write-Host "logic for subnet $_ (foreach-object)"
    }
}

Edit: Your approach wasn't working because the subnets are a string array and the subnets are not named properties/noteproperties. You can see this by doing the following.

# This tells you it's an array of "objects" with properties Length, Rank etc
Get-Member -InputObject $json_sitesandsnets.Denver

# This pipes the array elements, telling you they are strings with Length property
# In powershell strings are an object that only have properties Chars/Length
$json_sitesandsnets.Denver | Get-Member

# To only return the types
$json_sitesandsnets.Denver.GetType()
$json_sitesandsnets.Denver[0].GetType()

It looks like to me that what you want is this.

foreach ($site in $json_sitesandsnets.PSObject.Properties) {
    Write-Host $site.Name -ForegroundColor Cyan
    $site.Value | Out-String | Write-Host 
}

Output

输出 #1

For the subnet values, the not properties are Orlando and Denver . You got that part right however your $site| get-member $site| get-member line shouldn't be there. Instead, you can access the value through $site.value directly. If you needto do something more, you can loop through these values, like this:

$index = 0
Foreach ($subnet in $site.Value) {
    Write-Host "$($index): $subnet"
    $index+=1
}

Output

输出#2

I don't suppose the json could be like this? The resulting object array in powershell would be easier to work with. It could almost be a csv.

[
  {
    "site": "Orlando",
    "subnets": [
      "10.10.10.0/24",
      "10.10.20.0/24",
      "10.10.30.0/24",
      "10.10.40.0/24"
    ]
  },
  {
    "site": "Denver",
    "subnets": [
      "10.0.70.0/24",
      "10.0.80.0/24",
      "10.0.90.0/24",
      "10.0.100.0/24"
    ]
  }
]


cat sites.json | convertfrom-json     

site    subnets
----    -------
Orlando {10.10.10.0/24, 10.10.20.0/24, 10.10.30.0/24, 10.10.40.0/24}
Denver  {10.0.70.0/24, 10.0.80.0/24, 10.0.90.0/24, 10.0.100.0/24}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM