2

I'm trying to convert data to JSON as input for a REST API. The challenge I have is that the data should consist of multiple depths (For a lack of better words). The code I'm using now is:

(@{name = "Contoso"; all_assets = "false"; all_users="false"; rules= @{type="fqdn"; operator="match"; terms=@("contoso") } }| ConvertTo-Json)

the output now is:

{
    "all_users":  "false",
    "name":  "Contoso",
    "all_assets":  "false",
    "rules":  {
                  "operator":  "match",
                  "terms":  [
                                "contoso"
                            ],
                  "type":  "fqdn"
              }
}

The REST-Api is complaining that the data contains invalid characters. Looking at the output, the section "rules:" contains { } instead of [ ]. I've been trying all kinds of tricks but I can't seem to figure this one out.

Anyone know what I'm doing wrong here?

  • Does this answer your question? [Unexpected ConvertTo-Json results? Answer: it has a default -Depth of 2](https://stackoverflow.com/questions/53583677/unexpected-convertto-json-results-answer-it-has-a-default-depth-of-2) – iRon Nov 20 '19 at 16:05

2 Answers2

4

If you want rules to contain an array of objects instead of an object with properties, enclose everything that goes inside the rules with @().

Because terms then becomes the 3rd level, you need to add parameter -Depth to the ConvertTo-Json cmdlet:

For better readability, I didn't do this as one-liner

@{ 
   name       = "Contoso"
   all_assets = "false"
   all_users  = "false"
   rules      = @(
                   @{
                      type     = "fqdn"
                      operator = "match"
                      terms    = @("contoso")
                   }
                )
} | ConvertTo-Json -Depth 3

Output:

{
    "all_users":  "false",
    "name":  "Contoso",
    "all_assets":  "false",
    "rules":  [
                  {
                      "operator":  "match",
                      "terms":  [
                                    "contoso"
                                ],
                      "type":  "fqdn"
                  }
              ]
}
Theo
  • 57,719
  • 8
  • 24
  • 41
  • Thanks Theo! The code example you gave seems to be giving the correct output. However, When using it with the Invoke-RestMethod, i'm still getting the following error: {"error":"Invalid JSON: unexpected character at line: 1, column: 11"} No Idea what could be wrong here. I've compared the example json data that Tenable has on their API access site and it looks exactly the same. – Michael Waterman Nov 20 '19 at 15:00
  • @MichaelWaterman Strange indeed... What happens if you send the json commpressed? For that use `ConvertTo-Json -Depth 3 -Compress` – Theo Nov 20 '19 at 15:05
  • The same error message. I did some testing. If I create a variable $body with the exact same code that originally comes after the -Body, replace the original code with the variable $body, it works. I would almost suspect a timing issue here. – Michael Waterman Nov 20 '19 at 15:22
  • @MichaelWaterman You didn't show how you are calling the `Invoke-RestMethod` using the json as body. Storing it inside a variable always makes sure the json is complete, but otherwise, you could put the code inside round brackets to ensure the same. (Storing it in a variable first wil make the code more readable IMO) – Theo Nov 20 '19 at 15:36
  • I've come to that conclusion as well. Thanks for the help Theo, appreciate it. – Michael Waterman Nov 20 '19 at 15:51
0

For what it's worth...
Not the answer to the Unexpected ConvertTo-Json results? Answer: it has a default -Depth of 2 issue, but how you might generally build a PowerShell expression from a Json file using ConvertTo-Expression cmdlet:

'{
    "all_users":  "false",
    "name":  "Contoso",
    "all_assets":  "false",
    "rules":  [
                  {
                      "operator":  "match",
                      "terms":  [
                                    "contoso"
                                ],
                      "type":  "fqdn"
                  }
              ]
}' | ConvertFrom-Json | ConvertTo-Expression

[pscustomobject]@{
        'all_users' = 'false'
        'name' = 'Contoso'
        'all_assets' = 'false'
        'rules' = ,[pscustomobject]@{
                'operator' = 'match'
                'terms' = ,'contoso'
                'type' = 'fqdn'
        }
}
iRon
  • 20,463
  • 10
  • 53
  • 79