Iterating through key names from a PSCustomObject

瘦欲@ 提交于 2019-12-21 03:37:21

问题


I am writing a script for my site that utilizes a JSON configuration file. The JSON is similar to the following:

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

To convert the object to something PowerShell can read, I use ConvertFrom-Json which converts it to type PSCustomObject.

I am at a point where I have to iterate over the Groups and get each group name to output them and their corresponding index within the configuration's Groups object. That is,

1. GroupOne
2. GroupTwo
3. GroupThree

The furthest I have gotten is:

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

And all this does is output something that looks like PowerShell array notation:

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

Is this even possible with a PSCustomObject type? I primarily code in JavaScript so perhaps I am oversimplifying (or overcomplicating it) the issue since this would be relatively easy.


回答1:


Solution

I'm not sure how early of a version you can do this with, but it works for me in PowerShell 5.1... Feel free to give it a try in earlier versions:

$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.
}

Outputs

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
--

This is all done with PowerShell 4.0; ConvertTo-Json and ConvertFrom-Json were introduced in PowerShell 3.0; I haven't tested PowerShell 3.0 or 5.0.


Another Example

Try it for yourself with another example:

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

Outputs

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
--

This and other PowerShell looping are available on my blog.




回答2:


I think I might have just figured it out thanks to the blog post Converting PsCustomObject To/From Hashtables.

Using Get-Member and then -MemberType exposes each Group and then you just pull the:

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

Outputs:

GroupOne
GroupTwo
GroupThree

I'm open to any other methods though.

Update

I've found another way, but the only drawback is it doesn't use the fancy ConvertFrom-Json CmdLet. Instead it goes straight to the .NET library and uses its deserializer and converts it to a HashTable. This completely avoids having to muddle around with the PSCustomObject. IMO hashtables are a whole lot easier to work with.

$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)"
}


来源:https://stackoverflow.com/questions/18779762/iterating-through-key-names-from-a-pscustomobject

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!