Building JSON Payload in Powershell

When we’re building JSON payload in Powershell, there are a number of things to consider. What are our object types in Powershell? How to combine multiple Powershell Objects to one JSON object? How is the API going to read and parse that payload? For the purposes of this post I’ll be demoing against the Log Analytics public API in which sending a JSON payload is creates a custom log in our workspace.

 

JSON Notation

In its most simplest form JSON is key and value pair.

{

"key1" : "value1"

}

 

Building JSON Payload in Powershell

If you’ve read my post on monitoring your BBQ with Powershell, you know that you can simply build a key value pair JSON object in Powershell. By declaring the variable and submitting the keys and values inside curly braces.

$json = @"
{
"Pit Target Temp": $pitTargettemp,
"Fan % Output": $pitfan_output,
"Food 1 Target": $food1targettemp,
"Pit Temp": $pittemp,
"Food1 Temp": $food1temp,
"Cook Name": "$cook"
}
"@

This is the simplest way to create a JSON object. But what if you have a Powershell Object with multiple fields?

ConvertTo-JSON

From my series about using APIs with Powershell, we know that we have ConvertTo-JSON and ConvertFrom-JSON cmdlets. These work amazingly well for single PS Object conversions.

Lets say we get a bunch of services with the below one liner.


$service = get-service | where-object {$_.name -like '*vm*'} | select-object name, status, displayname

converto-json $service

then converting that output to JSON, we would get both the below outputs for our PSObject and JSON object respectively.

building JSON payload with powershell building JSON payload in powershell

note I cut off the JSON output for brevity of the screen grab.

The important bit here is that Log Analytics will ingest this JSON with no problem and considers each set of values after each comma as a separate log. This is great if you have a bunch of entries to send at once, however if you combine multiple PS objects into one and convert it to JSON this is not a good thing.

services_CL
| project Name_s, Status_d, DisplayName_s 

Using the above query gets us the logs we submitted. Exactly as it was submitted.

build json Payload powershell log analytics

API Specific Payloads with multiple PSObjects

Finally, what if we have multiple PSobjects each with multiple fields we want to send to an API? Take the below sample for instance. This was taken from 3 different SolarEdge APIs and combined, using something similar to this.


$solar1 = @()
$solar2 = @{}
$solar1 += $c.reporters.list
$solar2['payload'] = $solar1
$solar2 | ConvertTo-Json

build json Payload powershell log analytics

Unfortunately, even though the entire object is inside the brackets, each comma is treated as a separate log when ingested by Log Analytics. As you can see in the below screen grab, not an ideal log.

JSON custom log analytics

I’ve looked and looked and researched and the best way I can find to solve this is simply by using Add-Member. If you know of a better or more efficient way, I’m all ears.


#Build JSON Output, grabbing Inventory data, connected Optimizers and Status
$solar = $status.details | select-object Status, peakpower, lastupdatetime
$westarray = $inv.inventory.inverters | where-object {$_.name -eq "Inverter 2"}
$eastarray = $inv.inventory.inverters | where-object {$_.name -eq "Inverter 1"}

#Build final JSON adding Current Power, Total Power for the day and inventory data to Solar variable
$solar | add-member -name WestInverter -value $westarray.name -MemberType NoteProperty
$solar | add-member -name WestCPUVersion -value $westarray.cpuVersion -MemberType NoteProperty
$solar | add-member -name WestPanelCount -value $westarray.connectedOptimizers -MemberType NoteProperty
$solar | add-member -name EastInverter -value $eastarray.name -MemberType NoteProperty
$solar | add-member -name EastCPUVersion -value $eastarray.cpuVersion -MemberType NoteProperty
$solar | add-member -name EastPanelCount -value $eastarray.connectedOptimizers -MemberType NoteProperty
$solar | add-member -name CurrentOutput -value $power.overview.currentPower.power -MemberType NoteProperty
$solar | Add-Member -name TodaysOutput -value $power.overview.lastDayData.energy -MemberType NoteProperty

this sample starts after grabbing the data from each API. I will show this in a later post thats more specific to data collection from the SolarEdge API.

 

custom json Payload powershell log analytics

Summary

When building a JSON payload you’ll definitely want to read the API’s documentation to see how it wants a handle your payload. Then work towards building your final payload using the best method that works for you and the data that you’re submitting.

Leave a Comment