在 PowerShell 中循环遍历 PSObject 中的属性(来自 json)
Looping through properties inside a PSObject in PowerShell (from json)
在 PowerShell 中打开 .json 文件后,我得到了一个名为 $json_sitesandsnets 的新 PSObject。最终我想做的是循环遍历每个站点(奥兰多、丹佛),循环遍历它们的每个子网,然后做一些事情。最初,我需要使用 New-ADReplicationSubnet cmdlet 为 Active Directory 中的相应站点创建这些子网。我已经使用它来创建一个子网,但我有一个更大的站点和子网列表,我将使用它。这个例子只是 post 的一个小的精简版本。一旦我弄清楚如何访问对象值中的那些子网,我可能只需将每个子网列表提供给 New-ADReplicationSubnet。但我真的希望能够出于其他目的遍历每个子网。我想这可能并不难,只要你知道怎么做。
这是原始的 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"
]
}
然后我得到了这样的 PSObject 属性:
$json_sitesandsnets.psobject.properties
PSObject properties
当我 运行 在 VSCode 中调试时,我可以看到 PSObject 和子网列表(数组):
seeing this in Debug
这是一些代码,它获取名称没问题 (Write-Host $site.Name)。如您所见,我尝试了几种不同的方式来访问这些子网,这是每个站点的价值。我就是想不通。我已经阅读了很多关于遍历 PSObjects 的文章和论坛主题,但似乎无法找到访问和循环遍历作为 PSObject 值的数组的黄金答案。我觉得我真的很亲近。
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
}
}
您可以通过使用网站名称建立索引来做到这一点。 $json_sitesandsnets.($site.Name)
我也会在 foreach
中使用 $json_sitesandsnets.PSObject.Properties.Name
而不是 $json_sitesandsnets.PSObject.Properties
,以简化事情:
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)"
}
}
编辑: 您的方法无效,因为子网是字符串数组并且子网未命名 properties/noteproperties。您可以通过执行以下操作来查看。
# 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()
在我看来,你想要的是这个。
foreach ($site in $json_sitesandsnets.PSObject.Properties) {
Write-Host $site.Name -ForegroundColor Cyan
$site.Value | Out-String | Write-Host
}
输出
对于子网值,not 属性是 Orlando 和 Denver。
你做对了那部分,但是你的 $site| get-member
行不应该在那里。相反,您可以直接通过 $site.value
访问该值。
如果你需要做更多的事情,你可以遍历这些值,像这样:
$index = 0
Foreach ($subnet in $site.Value) {
Write-Host "$($index): $subnet"
$index+=1
}
输出
我想 json 不会是这样吧? powershell 中生成的对象数组将更易于使用。它几乎可以是一个 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}
在 PowerShell 中打开 .json 文件后,我得到了一个名为 $json_sitesandsnets 的新 PSObject。最终我想做的是循环遍历每个站点(奥兰多、丹佛),循环遍历它们的每个子网,然后做一些事情。最初,我需要使用 New-ADReplicationSubnet cmdlet 为 Active Directory 中的相应站点创建这些子网。我已经使用它来创建一个子网,但我有一个更大的站点和子网列表,我将使用它。这个例子只是 post 的一个小的精简版本。一旦我弄清楚如何访问对象值中的那些子网,我可能只需将每个子网列表提供给 New-ADReplicationSubnet。但我真的希望能够出于其他目的遍历每个子网。我想这可能并不难,只要你知道怎么做。
这是原始的 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"
]
}
然后我得到了这样的 PSObject 属性:
$json_sitesandsnets.psobject.properties
PSObject properties
当我 运行 在 VSCode 中调试时,我可以看到 PSObject 和子网列表(数组): seeing this in Debug
这是一些代码,它获取名称没问题 (Write-Host $site.Name)。如您所见,我尝试了几种不同的方式来访问这些子网,这是每个站点的价值。我就是想不通。我已经阅读了很多关于遍历 PSObjects 的文章和论坛主题,但似乎无法找到访问和循环遍历作为 PSObject 值的数组的黄金答案。我觉得我真的很亲近。
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
}
}
您可以通过使用网站名称建立索引来做到这一点。 $json_sitesandsnets.($site.Name)
我也会在 foreach
中使用 $json_sitesandsnets.PSObject.Properties.Name
而不是 $json_sitesandsnets.PSObject.Properties
,以简化事情:
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)"
}
}
编辑: 您的方法无效,因为子网是字符串数组并且子网未命名 properties/noteproperties。您可以通过执行以下操作来查看。
# 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()
在我看来,你想要的是这个。
foreach ($site in $json_sitesandsnets.PSObject.Properties) {
Write-Host $site.Name -ForegroundColor Cyan
$site.Value | Out-String | Write-Host
}
输出
对于子网值,not 属性是 Orlando 和 Denver。
你做对了那部分,但是你的 $site| get-member
行不应该在那里。相反,您可以直接通过 $site.value
访问该值。
如果你需要做更多的事情,你可以遍历这些值,像这样:
$index = 0
Foreach ($subnet in $site.Value) {
Write-Host "$($index): $subnet"
$index+=1
}
输出
我想 json 不会是这样吧? powershell 中生成的对象数组将更易于使用。它几乎可以是一个 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}