2016-08-03 37 views
3

Ich versuche, eine JSON-Datei in Powershell aufzunehmen, einen Block von JSON an einen vorhandenen Knoten (Komponenten) anzufügen, das PSCustomObject dann wieder in JSON zu konvertieren und die Datei zu speichern. Der JSON, mit dem ich spiele, sieht ungefähr wie Abbildung 1 aus.PSCustomObjects innerhalb des Arrays kann nicht korrekt in JSON konvertiert werden

Wie Sie in meinem Code sehen, führe ich ConvertTo-Json aus, um die Daten in ein PSCustomObject umzuwandeln, und anschließend ein neues Objekt an den Knoten Komponenten. Wenn ich das Objekt, $ configFile, in diesem Fall anschaue, sieht alles gut aus, aber wenn ich wieder in JSON konvertiere, werden die Elemente im Knoten Komponenten als Strings behandelt und nicht in JSON ausgewertet (siehe letztes Snippet). Ich stelle mir das vor, weil ConvertTo-JSON Arrays buchstäblich, aber nicht 100% sicher behandelt.

Wenn jemand angeben kann, wie sichergestellt wird, dass die PSCustomObjects im Komponentenknoten ordnungsgemäß an JSON übergeben werden, wäre ich Ihnen dankbar, danke.

Figur 1 - die ursprüngliche 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" 
     ] 
    } 
} 
} 

Abbildung 2 - mein Code:

#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 

Figur 3 - der JSON Ausgang:

{ 
"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" 
    } 
} 
} 

Wenn erhöhe ich die Tiefe zu sagen, 8 oder darüber hinaus, der JSON kommt wie folgt heraus:

{ 
"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" 
    } 
} 
} 
+0

Hmm, nur Konvertierung von JSON und Konvertierung zurück in JSON erzeugt eine Liste von serialisierten Objekten anstelle von JSON-Syntax-Objekten. Seltsam. – Vesper

Antwort

3

Das Cmdlet ConvertTo-Json verfügt auch über einen Depth-Parameter, über den hinaus ein Objekt mit toString() behandelt wird, anstatt tiefer in die Rekursion zu gehen. Wenn Sie also nur diesen Parameter auf die maximale Tiefe der Objekte setzen, die Sie haben, sollte dies zu einem korrekt erstellten JSON führen.

$configJson = ConvertTo-Json $configToPSObject -Depth 8 
# your JSON has depth of 5, get some extra 
+0

Hi, das passiert unabhängig davon, ob der Parameter -Depth angegeben ist. Entschuldigung, ich werde meinen Beitrag jetzt aktualisieren. – bleloch

+0

Kann nicht bestätigen. Wie auch immer, "etwas mehr Tiefe" Ansatz sollte funktionieren. Vielleicht habe ich etwas übersehen, während ich die Tiefe von JSON gemessen habe. – Vesper

+0

Wenn ich den -Depth-Parameter gebe ich bekomme "die konvertierte JSON-Zeichenfolge ist in schlechtem Format" Ich kann kein Problem mit der Formatierung jedoch finden, wie das neue Objekt vom gleichen Typ wie seine bereits bestehenden Geschwister ist. – bleloch

0

Sie müssen die Tiefe für das ConvertTo-Json-Commandlet angeben. Andernfalls tut es nur die erste Ebene und belässt die Unterknoten unverändert und wandelt sie scheinbar in eine Zeichenfolge um.

+0

Der Standardwert für 'Depth' ist übrigens 2, nicht 1. – Vesper

+0

Ah ic, sonst wäre das Components Array auch nicht analysiert worden. – n3wjack

+0

Bitte sehen Sie meine Antwort auf Vesper's Kommentar – bleloch