I have been having a problem while automating a task using API. The final JSON output of the Powershell script should look like this:
{
"scopes": [
{
"description": "someDescription",
"scopePath": "somePath"
}
],
"sources": [
{
"eventSource": "SecureScores"
},
{
"eventSource": "SecureScoreControls"
},
{
"eventSource": "SecureScoreControlsSnapshot"
},
{
"eventSource": "SecureScoresSnapshot"
}
],
"actions": [
{
"workspaceResourceId": "someWorkspace",
"actionType": "Workspace"
}
]
}
}
While using [] brackets after "actions" and "sources". However no matter what I try I always end up with something like this
"location": "Test",
"etag": "etag",
"properties": {
"Description": "some description",
"IsEnabled": "true",
"scopes": {
"scopePath": "scopePath",
"description": "scopeDescription",
"sources": {
"eventSource": "SecureScores",
"eventSource3": "SecureScoresSnapshot",
"eventSource2": "SecureScoreControlsSnapshot",
"eventSource1": "SecureScoreControls"
},
"actions": {
"actionType": "Workspace",
"workspaceResourceId": "someID"
}
}
}
}
With the wrong {} brackets. I need this to invoke a REST API code correctly. Any idea how to pass the variables so the JSON would then define those values in an array? I use something like $RESTjson = $RESTdata | ConvertTo-Json while in $RESTData is a hashtable. Example:
$RESTdata = @{
location = $Tags.Region
etag = "etag"
properties = @{
Description = "some description"
IsEnabled = "true"
scopes = @{
description = "scopeDescription"
scopePath = "scopePath"
}
sources = @{
eventSource = "SecureScores"
eventSource1 = "SecureScoreControls"
eventSource2 = "SecureScoreControlsSnapshot"
eventSource3 = "SecureScoresSnapshot"
}
actions = @{
workspaceResourceId = "someID"
actionType = "Workspace"
}
}
}
Tried messing with -Depth parameter of ConverTo-Json command but without any luck. Various definitons of input values but haven´t found the proper way yet.
CodePudding user response:
Wrap the lone hashtables in the @(...)
array subexpression operator to force PowerShell to wrap and store it in an array:
$RESTdata = @{
location = $Tags.Region
etag = "etag"
properties = @{
Description = "some description"
IsEnabled = "true"
scopes = @{
description = "scopeDescription"
scopePath = "scopePath"
}
sources = @(@{
eventSource = "SecureScores"
eventSource1 = "SecureScoreControls"
eventSource2 = "SecureScoreControlsSnapshot"
eventSource3 = "SecureScoresSnapshot"
})
actions = @(@{
workspaceResourceId = "someID"
actionType = "Workspace"
})
}
}
CodePudding user response:
- Use
@(...)
, the array-subexpression operator, around property values that must become arrays. - If you want to retain the definition order, use
[ordered]
hashtables (not strictly needed). - Use nested hashtables for those properties that must become their own JSON objects, such as
@{ eventSource = "SecureScores" }
to become{ "eventSource": "SecureScores" }
in JSON.
$RESTdata = [ordered] @{
location = $Tags.Region
etag = "etag"
properties = [ordered] @{
Description = "some description"
IsEnabled = "true"
scopes = @(
[ordered] @{
description = "scopeDescription"
scopePath = "scopePath"
}
)
sources = @(
@{ eventSource = "SecureScores" }
@{ eventSource = "SecureScoreControls" }
@{ eventSource = "SecureScoreControlsSnapshot" }
@{ eventSource = "SecureScoresSnapshot" }
)
actions = @(
[ordered] @{
workspaceResourceId = "someID"
actionType = "Workspace"
}
)
}
}
# This yields the desired output as shown in your question.
$RESTData | ConvertTo-Json -Depth 3
Note the unfortunate need to pass a -Depth
argument to ConvertTo-Json
to avoid data truncation - see this post.