Не удается правильно преобразовать PSCustomObjects в массиве обратно в JSON

Я пытаюсь вставить JSON-файл в Powershell, добавить блок JSON к существующему узлу (Компоненты), затем преобразовать PSCustomObject обратно в JSON и сохранить файл. JSON, с которым я играю, выглядит примерно так, как показано на рисунке 1.

Как вы видите из моего кода, я запускаю ConvertTo-Json для приведения данных в PSCustomObject, а затем добавляю новый объект в узел Components. Если я смотрю объект, $ configFile в этом случае все выглядит нормально, но когда я преобразую обратно в JSON, элементы в узле Компоненты обрабатываются как строки и не оцениваются в JSON (см. Последний фрагмент). Я предполагаю, что это потому, что ConvertTo-JSON обрабатывает массивы буквально, но не на 100% уверен.

Если кто-то может посоветовать, как обеспечить правильное приведение PSCustomObjects в узле Components к JSON, я был бы благодарен, спасибо.

Рисунок 1 - исходный JSON:

{
"EngineConfiguration": {
    "PollInterval": "00:00:15",
    "Components": [
        {
            "Id": "ApplicationEventLog",
            "FullName": "AWS.EC2.Windows.CloudWatch.EventLog.EventLogInputComponent,AWS.EC2.Windows.CloudWatch",
            "Parameters": {
                "LogName": "Application",
                "Levels": "1"
            }
        },
        {
            "Id": "SystemEventLog",
            "FullName": "AWS.EC2.Windows.CloudWatch.EventLog.EventLogInputComponent,AWS.EC2.Windows.CloudWatch",
            "Parameters": {
                "LogName": "System",
                "Levels": "7"
            }
        }
    ],
    "Flows": {
        "Flows": 
        [
            "(ApplicationEventLog,SystemEventLog),CloudWatchLogs"
        ]
    }
} 
}

Рисунок 2 - мой код:

#Requires -Version 3.0

$configFile = "C:\Program Files\Amazon\EC2ConfigService\Settings\AWS.EC2.Windows.CloudWatch.json"
$configToPSObject = ConvertFrom-Json "$(Get-Content $configFile)"

$configToPSObject.EngineConfiguration.Components += New-Object -Type PSObject -Property ([ordered]@{
"Id" = "IISRequestQueueSize"
"FullName" = "AWS.EC2.Windows.CloudWatch.PerformanceCounterComponent.PerformanceCounterInputComponent,AWS.EC2.Windows.CloudWatch"
"Parameters" = [PSCustomObject]@{
        "CategoryName" = "HTTP Service Request Queues"
        "CounterName" = "CurrentQueueSize"
        "InstanceName" = "_Total"
        "MetricName" = "IISRequestQueueSize"
        "Unit" = ""
        "DimensionName" = ""
        "DimensionValue" = ""
}
})

$configJson = ConvertTo-Json -Depth 5 $configToPSObject


Set-Content -Path $configFile -Value $configJson

Рисунок 3 - вывод JSON:

{
"EngineConfiguration":  {
    "PollInterval":  "00:00:15",
    "Components":  [
        "@{Id=ApplicationEventLog; FullName=AWS.EC2.Windows.CloudWatch.EventLog.EventLogInputComponent,AWS.EC2.Windows.CloudWatch; Parameters=}",
        "@{Id=SystemEventLog; FullName=AWS.EC2.Windows.CloudWatch.EventLog.EventLogInputComponent,AWS.EC2.Windows.CloudWatch; Parameters=}",
        "@{Id=IISRequestQueueSize; FullName=AWS.EC2.Windows.CloudWatch.PerformanceCounterComponent.PerformanceCounterInputComponent,AWS.EC2.Windows.CloudWatch; Parameters=}"
        ],
"Flows":  {
    "Flows": 
        "(ApplicationEventLog,SystemEventLog),CloudWatchLogs"
    }
}
}

Если я увеличу глубину до 8 или более, JSON получится следующим образом:

{
"EngineConfiguration":  {
   "PollInterval":  "00:00:15",
   "Components":  [
       "@{Id=ApplicationEventLog; FullName=AWS.EC2.Windows.CloudWatch.EventLog.EventLogInputComponent,AWS.EC2.Windows.CloudWatch; Parameters=}",
       "@{Id=SystemEventLog; FullName=AWS.EC2.Windows.CloudWatch.EventLog.EventLogInputComponent,AWS.EC2.Windows.CloudWatch; Parameters=}",
       "Id":  "IISRequestQueueSize",
       "FullName":  "AWS.EC2.Windows.CloudWatch.PerformanceCounterComponent.PerformanceCounterInputComponent,AWS.EC2.Windows.CloudWatch",
       "Parameters":  {                                                                        
           "CategoryName":  "HTTP Service Request Queues",
           "CounterName":  "CurrentQueueSize",
           "InstanceName":  "_Total",                                                                      
           "MetricName":  "IISRequestQueueSize",
           "Unit":  "",
           "DimensionName":  "",
           "DimensionValue":  ""
        }
    }
],
"Flows":  {
    "Flows":  "(ApplicationEventLog,SystemEventLog),CloudWatchLogs"
    }
}
}
 Vesper03 авг. 2016 г., 14:07
Хм, простое преобразование из JSON и обратное преобразование в JSON создает список сериализованных объектов вместо объектов JSON-синтаксиса. Weird.

Ответы на вопрос(2)

ConvertTo-Json Командлет также имеетDepth параметр, за которым объект обрабатываетсяtoString() вместо того, чтобы идти глубже с рекурсией. Так что просто установка этого параметра на максимальную глубину объектов, которые у вас есть, должна привести к правильно сформированному JSON.

$configJson = ConvertTo-Json $configToPSObject -Depth 8 
# your JSON has depth of 5, get some extra
 Vesper03 авг. 2016 г., 14:48
Не могу подтвердить. В любом случае, подход «использовать некоторую дополнительную глубину» должен работать. Может быть, я что-то упустил при измерении глубины вашего JSON.
 bleloch03 авг. 2016 г., 14:42
Привет, это происходит независимо от того, указан ли параметр -Depth. Извините, я обновлю свой пост сейчас.
 bleloch04 авг. 2016 г., 12:08
Если я укажу параметр -Depth, то получу «преобразованная строка JSON в неправильном формате», но я не смогу найти никаких проблем с форматированием, поскольку новый объект того же типа, что и ранее существовавшие братья и сестры.
 Vesper04 авг. 2016 г., 15:30
Снова не могу подтвердить. Пожалуйста, проверьте, соответствует ли ваш оригинальный файл тому, что написано в тексте вопроса, и если вы делаетепросто перечисленные операции, вы получите правильный JSON. Я просто сделал это, написал здесь строку из предоставленного вами JSON, а затем добавил объект вEngineConfiguration.Components, затем преобразовал объект while в JSON и получил действительный JSON со всеми преобразованными объектами. Возможно, даже проверьте на другом компьютере, может быть, ваша установка Powershell / .NET повреждена и влияет на этот код.

Вы должны указать глубину для командлета ConvertTo-Json. В противном случае он выполняет только первый уровень и оставляет подузлы как есть и, по-видимому, преобразует их в строку.

$configJson = ConvertTo-Json $obj -Depth 3
 bleloch03 авг. 2016 г., 14:42
Пожалуйста, смотрите мой ответ на комментарий Веспера
 Vesper03 авг. 2016 г., 14:13
Кстати, значение по умолчанию дляDepth 2, а не 1.
 jurgenb03 авг. 2016 г., 14:40
Да, в противном случае массив Components также не был бы проанализирован.

Ваш ответ на вопрос