2
votes

I need to perform an Invoke-Webrequest with a specifically formatted body to add devices to a product. Here is what it looks like in json (example straight from the vendor's documentation):

$body_json = '{"datasource": [{
            "parentId": "123456789000",
            "name": "(name)",
            "id": "(value)",
            "typeId": 0,
            "childEnabled": false,
            "childCount": 0,
            "childType": 0,
            "ipAddress": "(ipAddress)",
            "zoneId": 0,
            "url": "(url)",
            "enabled": false,
            "idmId": 123456789000,
            "parameters": [{
                "key": "(key)",
                "value": "(value)"
            }]
        }]}'

When I try to submit this in its json representation though, I get the following error:

Invoke-WebRequest : Can not deserialize instance of com.vendor.etc.DataSourceDetail out of START_ARRAY token at [Source: java.io.StringReader@22c614; line: 1, column: 1] At C:\powershell_script_location\ps.ps1:114 char 9 + $request = Invoke-WebRequest $url -Method Post -Headers $headers -Body $body_json - ... +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

The issue is with the format of the "parameters", parameter because the request submits fine when omitting the "parameters", but then the devices that I'm adding are missing important parameter details.

Is there something wrong with Invoke-WebRequest, JavaScriptSerializer, the vendor's code, or is this a user error? Let me know if any clarification is needed.

Unfortunately I don't know what a com.vendor.etc.DataSourceDetail instance looks like, as I am using an API and I don't have access to it directly.

2
Allow me to give you the standard advice to newcomers: If an answer solves your problem, please accept it by clicking the large check mark (✓) next to it and optionally also up-vote it (up-voting requires 15 or more reputation points). If you found other answers helpful, up-vote them. Accepting (for which you'll gain 2 reputation points) and up-voting help future readers. Please see the relevant help-center article. If your question isn't fully answered yet, please provide feedback or self-answer.mklement0

2 Answers

5
votes

Use Invoke-RestMethod instead of Invoke-WebRequest.

If you have the body as a string use:

Invoke-RestMethod -Uri http://your-url.com -Method POST -Body $body_json -ContentType "application/json"   

If the body must be constructed from data/parameters, it might be easier to build a hashtable and convert it to json via ConvertTo-Json:

$body_json = @{
    datasource = @(
        @{
            parentId = 123456789000
            name = "name"
            id = "value"
            typeId = 0
            childEnabled = $false
            childCount = 0
            childType = 0
            ipAddress = "ipAddress"
            zoneId = 0
            url = "url"
            enabled = $false
            idmId = 123456789000
            parameters = @( @{
                key = "key"
                value = "value"
            })
       })} | ConvertTo-Json -Depth 4

Invoke-RestMethod -Method 'Post' -Uri http://your-url.com -Body $body_json -ContentType "application/json"
0
votes

Body Undefined

I couldn't understand why the req.body on the server was undefined (NodeJS Azure Function). It turns out I had a header that was an empty string.

It's not clear whether is was invoke-restmethod or azure-functions-core-tools that has a bug.

FWIW.