Получение JSON с помощью PowerShell. Как получить все ключи в нескольких массивах?

Я пытаюсь создать файл json, который будет использоваться в наших разнообразных сценариях для получения сведений о нашем сервере. Один и тот же сценарий будет использоваться во всех наших средах, содержащих несколько продуктов и компонентов. Вот тип json-файла, с которым я работаю:

      {
    "DEV" : {
        "Product1" : [
            {"serverName" : "hostname1", "isWebServer" : "true"},
            {"serverName" : "hostname2", "isWebServer" : "false"}
        ],
        "Product2" : [
            {"serverName" : "hostname3", "isWebServer" : "false"},
            {"serverName" : "hostname4", "isWebServer" : "true"}
        ]
    }
}

Файл JSON импортируется в переменную, и я могу успешно его использовать.

$jsonFile = Get-Content -Path "C:\temp\test.json" -Raw | ConvertFrom-Json

Что я пытаюсь сделать в своем сценарии PowerShell, так это получить все имя сервера, настроенное с помощью ключа "isWebServer" : "true"

Я могу успешно достичь своей цели, если я буду углубляться в каждый массив напрямую.

($jsonFile.DEV.Product1 | Where-Object {$_.isWebServer -eq "true"}).serverName

Однако я не могу добиться такого же успеха, когда хочу получить все веб-серверы из всей среды DEV. Я ищу что-то подобное, но это действительно что-то вернет.

($jsonFile.DEV | Where-Object {$_.isWebServer -eq "true"}).serverName

Как я могу получить все во всех массивах внутри объекта? Я привык к XPATH, в которых я могу использовать подстановочные знаки для такого рода сценариев, но я не нашел эквивалента в JSON.

2 ответа

Вот возможное решение:

      $json.DEV.PSObject.Properties.Value.Where{ $_.isWebServer -eq 'true' }.serverName

Скрытое ( внутреннее ) PSObjectчлен позволяет нам получить доступ к свойствам ( Product1, Product2, ...) принадлежащий DEVобъекта, не зная заранее их имен.

Затем, используя перечисление доступа к членам , мы получаем массив всех Valueчлены PSPropertyInfoобъекты, хранящиеся в PSObject.Properties.

Для фильтрации объектов сервера встроенный метод Whereиспользуется для возврата только серверов, соответствующих заданному условию. Не стесняйтесь использовать Where-Objectвместо:

      $json.DEV.PSObject.Properties.Value | 
    Where-Object isWebServer -eq 'true' | 
    ForEach-Object serverName

Хотя я предпочитаю встроенные методы, поскольку они быстрее, чем конвейер (меньше накладных расходов), и их проще писать.

Это похоже на то, что я сделал давным-давно. Посмотрите, поможет ли это .

Другие вопросы по тегам