Home > Back-end >  Powershell - Sending an array to JSON
Powershell - Sending an array to JSON

Time:01-18

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.

  • Related