迭代 PSCustomObject 中的键名称

问题描述 投票:0回答:2

我正在为我的网站编写一个使用 JSON 配置文件的脚本。 JSON 类似于以下内容:

"Groups": {
    "GroupOne": {
        "NamingFilter": {
            "Not":"<SITE>-MJ*",
            "Has":"*WM,*WT"
        }
    },
    "GroupTwo": {
        "NamingFilter": {
            "Has":"<SITE>-MJ*, *WC,*WL"
        }
    },
    "GroupThree": {
        "NamingFilter": {
            "Not":"<SITE>-MJ*",
            "Has":"*WI"
        }
    }
}

要将对象转换为 PowerShell 可以读取的内容,我使用

ConvertFrom-Json
将其转换为类型
PSCustomObject

我现在必须迭代

Groups
并获取每个组名称以输出它们及其在配置的
Groups
对象中的相应索引。也就是说,

1. GroupOne
2. GroupTwo
3. GroupThree

我最远的是:

foreach ($group in $configObject.Groups) {
    $group
}

这一切所做的就是输出一些看起来像 PowerShell 数组符号的东西:

@{GroupOne=; GroupTwo=; GroupThree=;}

这对于

PSCustomObject
类型是否可能?我主要用 JavaScript 编写代码,所以也许我过于简单化(或过于复杂化)问题,因为这相对容易。

powershell-2.0 object-graph
2个回答
33
投票

解决方案

我不确定您可以在多早的版本中执行此操作,但它在 PowerShell 5.1 中对我有效...请随意在早期版本中尝试一下:

$ipinfo = Invoke-WebRequest 'http://ipinfo.io/json' -UseBasicParsing | ConvertFrom-Json
foreach ($info in $ipinfo.PSObject.Properties) {
    $info.Name
    $info.Value
    '--' # <-- Seeing this double hash proves we're iterating fully.
}

输出

ip
1.2.3.4
--
hostname
No Hostname
--
city
Denton
--
region
Texas
--
country
US
--
loc
33.2148,-97.1331
--
org
AS589 University of North Texas
--
postal
76203
--

这一切都是通过PowerShell 4.0完成的;

ConvertTo-Json
ConvertFrom-Json
是在 PowerShell 3.0 中引入的;我还没有测试过 PowerShell 3.0 或 5.0。


另一个例子

用另一个例子自己尝试一下:

$ipinfo = ConvertFrom-Json (Invoke-WebRequest 'http://ipinfo.io/json' -UseBasicParsing)
foreach ($info in ($ipinfo.PSObject.Members | ?{ $_.MemberType -eq 'NoteProperty'})) {
    $info.Name
    $info.Value
    '--'
}

输出

ip
1.2.3.4
--
hostname
No Hostname
--
city
Denton
--
region
Texas
--
country
US
--
loc
33.2148,-97.1331
--
org
AS589 University of North Texas
--
postal
76203
--

这个和其他 PowerShell 循环可以在我的博客上找到


12
投票

我想我可能刚刚弄清楚了,感谢博客文章将 PsCustomObject 与哈希表之间的转换

使用

Get-Member
然后使用
-MemberType
暴露每个组,然后你只需拉动:

foreach ($group in $configObject.Groups) {
    $groupName = $($group | Get-Member -MemberType *Property).Name
}

输出:

GroupOne
GroupTwo
GroupThree

不过,我对任何其他方法持开放态度。

更新

我找到了另一种方法,但唯一的缺点是它没有使用花哨的

ConvertFrom-Json
CmdLet。相反,它直接进入 .NET 库并使用其反序列化器并将其转换为哈希表。这完全避免了与 PSCustomObject 的混乱。 IMO 哈希表更容易使用。

$JSON = Get-Content -Path path/to.json -Raw
$HT = (New-Object System.Web.Script.Serialization.JavaScriptSerializer).Deserialize($JSON, [System.Collections.Hashtable])
$HT.Groups.GetEnumerator() | ForEach-Object {
    Write-Host "$($_.Key) : $($_.Value)"
}
© www.soinside.com 2019 - 2024. All rights reserved.