Не удается правильно преобразовать объекты PSCustomObject в массиве обратно в 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"
}
}
}
2 ответа
ConvertTo-Json
Командлет также имеет Depth
параметр, за которым объект обрабатывается toString()
вместо того, чтобы идти глубже с рекурсией. Так что просто установка этого параметра на максимальную глубину объектов, которые у вас есть, должна привести к правильно сформированному JSON.
$configJson = ConvertTo-Json $configToPSObject -Depth 8
# your JSON has depth of 5, get some extra
Вы должны указать глубину для командлета ConvertTo-Json. В противном случае он выполняет только первый уровень и оставляет подузлы как есть и, по-видимому, преобразует их в строку.
$configJson = ConvertTo-Json $obj -Depth 3