I'm trying to build a json file that'll be used in our diverse scripts to fetch our server details. The same script will be used across all our environments that contains multiple products and components. Here's the kind of json file I'm working with:
{
"DEV" : {
"Product1" : [
{"serverName" : "hostname1", "isWebServer" : "true"},
{"serverName" : "hostname2", "isWebServer" : "false"}
],
"Product2" : [
{"serverName" : "hostname3", "isWebServer" : "false"},
{"serverName" : "hostname4", "isWebServer" : "true"}
]
}
}
JSON file is imported into a variable and I'm able to use it successfully.
$jsonFile = Get-Content -Path "C:\temp\test.json" -Raw | ConvertFrom-Json
What I'm trying to do in my PowerShell script is fetch all serverName that is configured with key "isWebServer" : "true"
I can successfully achieve my goal if I'm drilling down on each arrays directly.
($jsonFile.DEV.Product1 | Where-Object {$_.isWebServer -eq "true"}).serverName
However, I'm unable to achieve the same success when I want to fetch all web servers from the whole DEV environment. I'm looking for something like this but that will actually return something.
($jsonFile.DEV | Where-Object {$_.isWebServer -eq "true"}).serverName
How can I fetch everything under all arrays within an object ? I'm used to XPATHs in which I can use wildcards for that kind of scenario but I haven't found the equivalent in JSON.
CodePudding user response:
Here is a possible solution:
$json.DEV.PSObject.Properties.Value.Where{ $_.isWebServer -eq 'true' }.serverName
The hidden (intrinsic) PSObject
member allows us to access properties (Product1
, Product2
, ...) of the DEV
object, without having to know their names in advance.
Then, using member access enumeration, we get an array of all Value
members of the PSPropertyInfo
objects stored in PSObject.Properties
.
To filter the server objects, the intrinsic method Where
is used to return only the servers matching the given condition. Feel free to use Where-Object
instead:
$json.DEV.PSObject.Properties.Value |
Where-Object isWebServer -eq 'true' |
ForEach-Object serverName
Though I prefer the intrinsic methods as they are faster than the pipeline (less overhead) and more succinct to write.
CodePudding user response:
It looks similar to what I did a long time ago. See if this helps.