Converting a working CURL to PowerShell Invoke-WebRequest

Hello,

I have been writing some PowerShell API utilities converting from working CURL requests. Generally been pretty successful in getting both GET & POST PowerShell equivalents to work. Ran into a brick wall on this POST request below however and just cannot figure out the correct array syntax. I have done simpler arrays OK, but the syntax for the “changes”, component of the CURL --data-binary item is what I am having trouble with (I think). I have tried a lot of combinations based on reading other references out there but still am stumbling on this. Any Help is appreciated…

The working CURL is:

[pre]

curl -k ‘https://10.x.x.x:3000/zx/api/v3/host_sets/static’ -X ‘POST’ --data-binary ‘{“name”:“Test”,“changes”:[{“command”:“change”,“add”:[“b4s42mSuRlbe8F4vwiSJGC”],“remove”:[]}]}’ -H ‘X-FeApi-Token: IPTzzzaDtYvOYJnaCorqpGnQFUAM123c6u6A3CKzwcASc=’ -H ‘Accept: application/json’ -H ‘Content-Type: application/json’

[/pre]

My problematic PowerShell conversion:

[pre]

API Utility

$FEAPI_Token=$args[0]
$Uri = $args[1]
$postParams = @(@{
“name”=“example”
“changes” = @(@{
“command”=“change”;
“add”=“b4s42mSuRlbe8F4vwiSJGC”
})}) | ConvertTo-Json

write-host $postParams

The write-host above is to just look at what the array looks like.

$Headers = @{
“Accept”=“application/json”
“Content-Type”=“application/json”
‘X-FeApi-Token’ = $FEAPI_Token
}

$resp = Invoke-WebRequest -Method Post -Uri $Uri -Headers $Headers -Body $postParams
write-host $resp

[/pre]

The output from running the PowerShell:

PS C:\Users\sa-tkinkel> c:\Powershell\FEAPI_PostIt1.ps1 IL7zzxxyyEWUdkBHMffkRxa3kNTid1234IMdIYTAT8= https://10.x.x.x:3000/hx/api/v3/host_sets/static
{
"name": "Test",
"changes": [
{
"add": "b4s42mSuRlbe8F4vwiSJGC",
"command": "change"
}
]
}
Invoke-WebRequest : {"details":[{"type":"error","code":2007,"path":"changes[0].add","message":"should be 
array","details":["array"]}],"route":"/hx/api/v3/host_sets/static","message":"Unprocessable Entity"}
At C:\Powershell\FEAPI_PostIt1.ps1:21 char:9
+ $resp = Invoke-WebRequest -Method Post -Uri $Uri -Headers $Headers -Body $postPa ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

 

 

Can you try executing this by hardcoding the json ?

$Json = '{"name":"Test","changes":[{"command":"change","add":["b4s42mSuRlbe8F4vwiSJGC"],"remove":[]}]}'
Invoke-RestMethod -Uri $Uri -Body $Json -ContentType Application/Json -Headers @{'X-FeApi-Token' = $FEAPI_Token} -Method Post

Hi Terry,

When using the ConvertTo-Json Cmdlet, if you pipe the PowerShell object to ConvertTo-Json, it compresses the object and will not expand the array you are looking for. Try doing it like this:

$FEAPI_Token=$args[0]
$Uri = $args[1]
$postParams = @(
    @{
        "name"="example"
        "changes" = @(
            @{
                "command"="change";
                "add"= @(
                    "b4s42mSuRlbe8F4vwiSJGC"
                )       
            }           
        )   
    }
)

$Body = ConvertTo-Json -InputObject $postParams -Depth 4

$Headers = @{
    "Accept"="application/json"
    "Content-Type"="application/json"
    'X-FeApi-Token' = $FEAPI_Token
}

$resp = Invoke-RestMethod Post -Uri $Uri -Headers $Headers -Body $Body

As suggested by @kvprasoon, use the Invoke-RestMethod Cmdlet when calling a Rest API.

pwshliquori

kvprasoon
Hardcoding the JSON worked fine (much simpler). I am going to play with this approach more and see if I can expand on it without getting into trouble. THANK YOU for your response.
pwshliquori
Thanks for responding. The different postParams approach (not sure what the proper nomenclature is; maybe nested array?? still giving me fits) your suggestion did change the response though to:
Invoke-RestMethod : {"details":[{"type":"error","code":2007,"path":"","message":"should be 
object","details":["object"]}],"route":"/hx/api/v3/host_sets/static","message":"Unprocessable Entity"}
At C:\Powershell\FEAPI_PostIt3.ps1:43 char:9
+ $resp = Invoke-RestMethod -Method POST -Uri $Uri -Headers $Headers -Body $Body
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
Full Code now with this approach:
[pre]

API Utility

$FEAPI_Token=$args[0]
$Uri = $args[1]
$postParams = @(
@{
“name”=“example”
“changes” = @(
@{
“command”=“change”;
“add”= @(
“b4s42mSuRlbe8F4vwiSJGC”
)
}
)
}
)

$Body = ConvertTo-Json -InputObject $postParams -Depth 4write-host $Body

The write-host above is to just look at what the array looks like.

$Headers = @{
“Accept”=“application/json”
“Content-Type”=“application/json”
“X-FeApi-Token” = $FEAPI_Token
}

$resp = Invoke-RestMethod -Method POST -Uri $Uri -Headers $Headers -Body $Body
write-host $resp

[/pre]

 

kvprasoon

Hardcoding the JSON worked fine (much simpler). I am going to play with this approach more and see if I can expand on it without getting into trouble. THANK YOU for your response.

pwshliquori

Thanks for responding. The different postParams approach (not sure what the proper nomenclature is; maybe nested array?? still giving me fits) your suggestion did change the response though to:Invoke-RestMethod :

{"details":[{"type":"error","code":2007,"path":"","message":"should be 
object","details":["object"]}],"route":"/hx/api/v3/host_sets/static","message":"Unprocessable Entity"}
At C:\Powershell\FEAPI_PostIt3.ps1:43 char:9
+ $resp = Invoke-RestMethod -Method POST -Uri $Uri -Headers $Headers -Body $Body
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommandFull Code now with this approach:[pre]## API Utility$FEAPI_Token=$args[0]$Uri = $args[1]$postParams = @(@{"name"="example""changes" = @(@{"command"="change";"add"= @("b4s42mSuRlbe8F4vwiSJGC")})})$Body = ConvertTo-Json -InputObject $postParams -Depth 4write-host $Body# The write-host above is to just look at what the array looks like.$Headers = @{"Accept"="application/json""Content-Type"="application/json""X-FeApi-Token" = $FEAPI_Token}$resp = Invoke-RestMethod -Method POST -Uri $Uri -Headers $Headers -Body $Bodywrite-host $resp[/pre]