boomcubist
boomcubist

Reputation: 881

Create a json document based on existing document with powershell 5.1

I'm trying to build a json document which takes it's structure, column names and some values from an already existing base json document, and sets other values to variables assigned via powershell 5.1 in a foreach-object loop.

I tried editing a copy of the base json and creating a new one entirely and I can get close to what I want but not exactly.

A cut down example json document is:

[
    {
        "name": "Application1",
        "tags": ["monitor"],
        "description": "Get information about application 1.",
        "query":
        [
            {                                                         
                "target": {                                                             
                    "version": ["v1","v2","v3","v4","v5"],
                    "platform": ["Windows","Linux"]
                },
                "implementation": {                                                      
                    "action": "do something"
                }
            }
        ]
    },
    {
        "name": "Application2",
        "tags": ["monitor"],
        "description": "Get information about application 2",
        "query":
        [
            {                                                     
                "target": {                                                             
                    "version": ["v1","v2","v3"],
                    "platform": ["Windows"]
                },
                "implementation": {                                                    
                    "action": "do something for v1, v2 and v3"
                }
            },
            {                                                     
                "target": {                                                             
                    "version": ["v4","v5"],
                    "platform": ["Windows"]
                },
                "implementation": {                                                    
                    "action": "do something for v4 and v5"
                }
            }
        ]
    }
]

My script currently looks like:

$BaseJson = (Get-Content "$SourcePath\probes.json" | ConvertFrom-Json)

$ClientConfig = @"
{
    "targetHost": "$DigitalSymphonyHost",
    "targetPort": "$DigitalSymphonyPort",
    "source": "$TargetSqlInstance",
    "sensor": {}
}
"@

$ClientJson = ConvertFrom-Json -InputObject $ClientConfig

$BaseJson | Where-Object {$_.tags -contains "monitor"} | ForEach-Object {
    # For each sensor in the base-sensors json document
    $SensorName = $_.name 
    $Severity = 2
    $Version = $_.query.target.version
    $Platform = $_.query.target.platform
    $Query = $_.query.implementation.action

    $Sensor =@"
                {
                    "severity": "$Severity",
                    "sensorId": "$SensorId",
                    "type": "$Type",
                    "target": {
                        "version": "$Version",
                        "platform": "$Platform",
                        "engineEdition": "$Edition"
                    },
                    "implementation": {
                        "query": "$Query"
                    }
                }
"@
    $ClientJson.sensor | Add-Member -Name $SensorName -Value (ConvertFrom-Json $Sensor) -MemberType NoteProperty
}

$ClientJson | ConvertTo-Json | Out-File "$DestinationPath\client-sensors.json"

My desired result is to add the $SensorId as per:

[
    {
        "targetHost":  "servername",
        "targetPort":  "port",
        "source":  "servername",
        "sensor":  [{
            "name": "Application1",
            "sensorId": "<value_from_$SensorId>",
            "tags": [],
            "description": "Get information about application 1.",
            "query":
            [
                {                                                         
                    "target": {                                                             
                        "version": ["v1","v2","v3","v4","v5"],
                        "platform": ["Windows","Linux"]
                    },
                    "implementation": {                                                      
                        "action": "do something"
                    }
                }
            ]
        },
        {
            "name": "Application2",
            "sensorId": "<value_from_$SensorId>",
            "tags": [],
            "description": "Get information about application 2",
            "query":
            [
                {                                                     
                    "target": {                                                             
                        "version": ["v1","v2","v3"],
                        "platform": ["Windows"]
                    },
                    "implementation": {                                                    
                        "action": "do something for v1, v2 and v3"
                    }
                },
                {                                                     
                    "target": {                                                             
                        "version": ["v4","v5"],
                        "platform": ["Windows"]
                    },
                    "implementation": {                                                    
                        "action": "do something for v4 and v5"
                    }
                }
            ]
        }]
    }
]

My current result is

{
    "targetHost":  "servername",
    "targetPort":  "port",
    "source":  "server",
    "sensor":  {
                   "applicationname1":  {
                                    "tags": ["monitor],
                                    "description": "Get information about application 2",
                                    "sensorId":  "420",
                                    "target":  "@{version=v1,v2,v3,v4,v5; platform=Windows Windows;}",
                                    "action":  "do something for v4 and v5"
                                }
                            }
}

Upvotes: 1

Views: 50

Answers (1)

derekbaker783
derekbaker783

Reputation: 9601

I'm not sure where you're getting sensorID, but I'd do this more like the below:

param(
    $SourcePath = $PSScriptRoot,
    $DestinationPath = $PSScriptRoot,
    $DigitalSymphonyHost = 'SomeHost',
    $DigitalSymphonyPort = '8765',
    $TargetSqlInstance
)

$BaseObj = (Get-Content "$SourcePath\probes.json" | ConvertFrom-Json)
$Client = [PSCustomObject] @{
    targetHost = $DigitalSymphonyHost
    targetPort = $DigitalSymphonyPort
    source = $TargetSqlInstance
    sensor = @()
}

$BaseObj | Where-Object {$_.tags -contains "monitor"} | ForEach-Object {
    $sensor = $_

    # TODO: How are you getting sensorId?
    $sensor | Add-Member -Name 'sensorId' -Value 777 -MemberType NoteProperty    
    $Client.sensor += $sensor 
}

ConvertTo-Json @($Client) -Depth 10 | Out-File "$DestinationPath\client-sensors.json" -Force

That will get you the JSON you're looking for.

Upvotes: 1

Related Questions