Search code examples
powershell-2.0object-graph

Iterating through key names from a PSCustomObject


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.


Solution

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