3

Very beginner question. I'm trying to get certain values from JSON with Powershell.. Specifically, I want to list the Services: TEST00000 and FAKE only.

When I run the script below, I get this:

TEST00000                                                    FAKE           
---------                                                    ----           
@{Enabled=True; Processed=2; Sent=3; Failed=4; Downloaded=5} @{Enabled=True}

How can I get a list of only the services?

More importantly, how do I list only the services which has the key/value Enabled=True present inside of them?

Here is the code:

$JSON = '{
  "Envs": {
    "DEV": {
      "Services": {
        "TEST00000": {
          "Enabled": true,
          "Processed": 2,
          "Sent": 3,
          "Failed": 4,
          "Downloaded": 5
        },
        "FAKE": {
          "Enabled": true
        }
      }
    }
  },
  "Component": {
    "Digger": {
      "Envs": {
        "DEV": {
          "DownloadE": 4
        }
      }
    }
  }
}'

$jsonobj = ConvertFrom-Json -inputObject $JSON

$jsonobj.Envs.DEV.Services
0

2 Answers 2

4

To get the name of each Services property. You can use Get-Member like user2734259 did or you can use the psobject property which stores useful information about an object.

$ServiceNames = $jsonobj.Envs.DEV.Services.psobject.properties.name

Once you have the names you can loop over them and filter on the sub-property Enabled

$jsonobj.Envs.DEV.Services.psobject.properties.name | ForEach-Object { 
    $_ | Where-Object {$jsonobj.Envs.DEV.Services.$_.Enabled -eq $True}
}
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you so much for the reply, this was super interesting, I spent a lot of time trying to look for this info, how did you guys learn this? Where can I do further reading about this? (or is it learning the art of using the PS help content!?)
@ToastMan I personally started with the Don Jones Month of Lunches books. Knowing about the hidden psobject property I picked up on from someone's answer on SO (been too long to remember who).
Hm the last part doesn't seem to work: $_ | Where-Object {$jsonobj.Envs.DEV.Services.$_.Enabled -eq 'false'} <-- lists the services anyways (with the -eq 'false')
@ToastMan Updated my answer to fix the issue. This was because the Enabled property is a boolean. And when you try to cast the string 'false' to a boolean, it turns into $True. You can test this with [bool]'false'.
1

This should allow you to get the names dynamically, regardless of the service name in your JSON:

$JSON = '{
  "Envs": {
    "DEV": {
      "Services": {
        "TEST00000": {
          "Enabled": true,
          "Processed": 2,
          "Sent": 3,
          "Failed": 4,
          "Downloaded": 5
        },
        "FAKE": {
          "Enabled": true
        }
      }
    }
  },
  "Component": {
    "Digger": {
      "Envs": {
        "DEV": {
          "DownloadE": 4
        }
      }
    }
  }
}'

$jsonobj = ConvertFrom-Json -inputObject $JSON
$enabledServices = $NULL
$disabledServices = $NULL

# Since the service names are arbitrary
# create an object that contains only
# objects whose MemberType is NoteProperty

$strServiceNames = @($($jsonobj.Envs.DEV.Services | Get-Member | Where { $_.MemberType -eq "NoteProperty" } | Select Name).Name)
$pscoServiceNames = [PSCustomObject]@{Names=$strServiceNames}
foreach($serviceName in $pscoserviceNames.Names)
{
    # dynamically access the service name
    # from $jsonobj.Envs.DEV.Services

    $serviceStatus = $jsonobj.Envs.DEV.Services.$serviceName.Enabled

    # parse results based on value of .Enabled

    if($serviceStatus.ToString() -eq "True")
    {
        $enabledServices = [Array]$enabledServices + [PSCustomObject]@{Name = $serviceName;Enabled = $serviceStatus}
    }
    else
    {
        $disabledServices = [Array]$disabledServices + [PSCustomObject]@{Name = $serviceName;Enabled = $serviceStatus}
    }
}

# Show the results

Write-Output "`nEnabled Services`n"
$enabledServices | Format-List
Write-Output "`nDisabled Services`n"
$disabledServices | Format-List

If anything is unclear let me know and I can explain in more detail Hope this helps you out. Happy 'shelling!

6 Comments

Thank you so much for the reply, this was super interesting !
if($serviceStatus -eq "False") <-- gives me the exact same results: Enabled Services Name : FAKE Enabled : True Name : TEST00000 Enabled : True
@toastman I will revisit when I'm back at the machine where I wrote the code and fix if necessary and edit my answer for the sake of completeness. Think it might be a type problem but will check. Til then, happy holidays
Yep, it was a type error. $serviceStatus is boolean so it needed to be converted to a string to match the regex. So just change that one line to: if($serviceStatus.ToString() -eq "False") and it should work as needed
Many thanks trebleCode. I ended up marking BenH response as the solution as I used his code at the end. But I highly appreciate your help.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.