I'm trying to work out how to do OData updates using PowerShell as the client. I found the site services.odata.org to use for testing: http://services.odata.org/OData/OData.svc/$metadata.
I've tried this:
Invoke-RestMethod -Method Put -ContentType 'application/json' `
-Uri 'http://services.odata.org/V3/(S(k22mmq0ajlv45epd2psyysnd))/OData/OData.svc/Products(0)' `
-Body ( #{ Description = 'CheesyPeas' } | ConvertTo-Json )
but I get back
Invoke-RestMethod : <?xml version="1.0" encoding="utf-8"?>
<m:error xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<m:code />
<m:message xml:lang="en-US">
Error processing request stream. Type information must be specified for types that take part in inheritance.
</m:message>
</m:error>
At line:1 char:1
+ Invoke-RestMethod -Uri 'http://services.odata.org/V3/(S(k22mmq0ajlv45epd2psyysnd ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
I think this has something to do with the Navigation Properties. Ideally, I'd be testing against a simple entity with no Navigation Properties until I've got a basic PUT working but I can't find one. Can anyone help me get this working?
As the error said, you need to specify the type you send in the body.
Write your code like below:
Invoke-RestMethod -Method Put -ContentType 'application/json' `
-Uri 'http://services.odata.org/V3/(S(k22mmq0ajlv45epd2psyysnd))/OData/OData.svc/Products(0)' `
-Body ( #{ "odata.type" = 'ODataDemo.Product'; Description = 'CheesyPeas' } | ConvertTo-Json )
Related
I am creating a script to call a couple of endpoints in my service.
The calls look like this:
$scheduleResponse=(curl -Method 'POST' -Uri $baseUrl'/scheduletests' `
-Headers #{"Accept"="application/json";"Content-Type"="application/json"} `
-Body $body)
$scheduleContent=ConvertFrom-Json([String]::new($scheduleResponse.Content))
#Error checks here
$testId = [String]::new($scheduleContent.ScheduleTests.TestID)
$getTestResultsBody = '{"TestID":"' + $testId + '"}' #Hard-coding this value works.
$getResponse=(curl -Method 'POST' -Uri $baseUrl'/gettestresults' -Headers #{"Accept"="application/json";"Content-Type"="application/json"} -Body $getTestResultsBody)
My getResponse fails with this error message:
curl : Unable to read data from the transport connection: The
connection was closed. At C:\Development\Services\TESTService\Test
Clients\Caller.ps1:43 char:27 ... etResponse=(curl -Method 'POST'
-Uri $baseUrl'/gettestresults' -Heade ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : NotSpecified: (:) [Invoke-WebRequest], IOException
FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
I debugged my service and it is receiving the correct request and sending the correct response back.
If I hard-code testId in the getRequest, the whole script works. So my guess is that it has something to do with reading the test id from the first call.
Any pointers on what could be wrong?
I'm struggling for last week or more with sending rest api command from powershell to add host in AWX(from curl is working). When I sent one parameter is worki but I need to send also variables
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", "Basic $VfAwxTokenX")
$Headers.Add('Content-Type', 'application/json')
$body = #{
name = '$vmname'
variables = 'test'
}| ConvertTo-Json
write-output $body
$response = Invoke-RestMethod 'https://awx/api/v2/inventories/2/hosts/' -Method 'POST' -Headers $headers -UseBasicParsing -Body $body
and error what i get:
{
"name": "wewewe",
"variables": "test" } Invoke-RestMethod : {"variables":["Cannot parse as JSON (error: Expecting value: line 1 column 1 (char 0)) or
YAML (error: Input type str is not a dictionary)."]} At line:32
char:13
$response = Invoke-RestMethod 'https://awx/api ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod],
WebException
FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
Maybe any one of users had that issue and now how to overcome it?
According to my research, the parameter variables should be defined as JSON or YAML format. For more details, please refer to here.
For more details about how to call the API, please refer to the blog.
the problem was prosaic
variables = 'test'
if i put anything else then test is working :/
I am trying to do a simple invoke rest method request for my API Authentication, however the bearer token is displaying a truncated output. How do I display the output string entirely?
PS C:\WINDOWS\system32> Invoke-RestMethod -Method POST -Body $body -uri $uri
access_token
------------
gAAAAMAEzhS8pzLrV5I1d5CJuyLq0BbBHaBAFhLzs9Uqk3zUueEvyxJ3NQN5KrTpexrFi7aUYbgvDzA0nQf7caGddeIngxC0uGjpVBlT5AlHbddwDiQhb4Ruh2BQry9dhmzN47Mz840FAU8WOrtQNXEundiaaN30nqel2365TEZc1uU15AIAAIAAAAAc_fYAsOVgvBOlg7QKGxgMbewrxaav-eprjqci9mCFQtfke...
I have tried addting the Out-String on the end but it shows me this error:
Invoke-RestMethod : A positional parameter cannot be found that accepts argument 'Out-String'.
At line:1 char:1
+ Invoke-RestMethod -Method POST -Body $body -uri $uri Out-String -Widt ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Invoke-RestMethod], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
You can add | Select-Object -ExpandProperty access_token to show the entire string value.
Using Select-Object -ExpandProperty will enumerate the value of the property that you pipe to it and output the value as a single record.
So instead of getting
access_token
------------
abcdefg1234....
you get
abcdefg1234567890
Print the property directly
(Invoke-RestMethod -Method POST -Body $body -uri $uri).access_token
So, here is the link to Jobs API call in Databricks here
Everything works in Python using requests. E.g both the job creation and job listing works
import requests
proxy= "http://127.0.0.1:8888"
access_token="tokenabc"
proxies = {
"https": proxy,
}
header_read = {
'Authorization': "Bearer " + access_token,
'Accept': "application/scim+json"
}
#list jobs
init_get=requests.get('https://databricksworkspaceid.azuredatabricks.net/api/2.0/jobs/list', headers=header_read, proxies=proxies)
#create job
init_post=requests.post('https://databricksworkspaceid.azuredatabricks.net/api/2.0/jobs/create', headers=header_read, proxies=proxies,verify=False,json=job_payload)
However, strangely in Powershell, only the job creation works and Job listing fails.
#this works
Invoke-RestMethod -Uri 'https://databricksworkspaceid.azuredatabricks.net/api/2.0/jobs/create' -Headers #{ 'Authorization' = "Bearer $bearertoken" } -Method Post -Body $content -ContentType 'application/json'
#this does not work
Invoke-WebRequest -Uri 'https://databricksworkspaceid.azuredatabricks.net/api/2.0/jobs/list' -Headers #{ 'Authorization' = "Bearer $bearertoken" } -Method Get
#RestMethod also does not work
Invoke-RestMethod -Uri 'https://databricksworkspaceid.azuredatabricks.net/api/2.0/jobs/list' -Headers #{ 'Authorization' = "Bearer $bearertoken" } -Method Get
I have also tried setting the Content type on these but nothing helps.
Also, explicitly setting the proxy (fiddler) does not help.
-proxy "http://127.0.0.1:8888"
But should not be the proxy also , as the post method works.
I just keep getting an error like
Invoke-WebRequest : The underlying connection was closed: An unexpected error occurred on a send.
At line:22 char:5
+ Invoke-WebRequest -Uri 'https://databricksworkspaceid.azuredatabricks.net/ap ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
or in case of RestMethod
Invoke-RestMethod : The underlying connection was closed: An unexpected error occurred on a send.
At line:22 char:5
+ Invoke-RestMethod -Uri 'https://databricksworkspaceid.azuredatabricks.net/ap ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
I could have understood if everything failed in Powershell, but the post method (job creation) works, so not sure, why the connection would be terminated in case of a Get request but not a post.
Going by some forum posts, I have also tried the following but to no avail-
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Does anyone know what am I doing wrong/missing? Baffling to see working in python but only a part in Powershell.
So, I finally found the answer. Basically 2 things:
Had to do this before hitting the list endpoint (strangely as I said- the create endpoint) worked
Basically allowing TLS, TLS1.1 and TLS1.2
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12
Doing only point 1 didn't work. I HAD to also use an "elevated" powershell session. Basically running the script with step 1 included, using a "Run as Administrator".
I'm attempting to use a REST API where I can add a list of items via a POST. However, I cannot seem to get the format of the body correct. The documentation says it's looking for a parameter called "data" that's type is body and the data type is an array. The sample provided for data, shows ["String","String","String"] I've asked for help on the vendors forums, but few users seem to use PowerShell.
I receive the following error:
"Invoke-RestMethod : {"message":"Request body must be populated for body parameter \"data\"","details":{},"description":"","code":10,"http_response":{"message":"The request was well-formed but was unable to be followed due to semantic errors","code":422}}"
I've tried many different formats for the body, but none seem to take. Here's an example of what I've been attempting:
$apiKey = "XXXXXXXXXXXXXXXXXXXXXX"
$url = "https://X.X.com"
$URI = "https://X.X.com/api/reference_data/sets/bulk_load/APITest"
Invoke-RestMethod -Method Post -Uri $URI -Body (convertto-json $body) -Header #{"SEC"= $apiKey }
$body = #{"10.10.1.5","10.10.1.5","50.50.50.50","123.45.6.7"}
I've also tried something like:
$body = #{"data"="body";"value"="10.10.1.5","50.50.50.50","123.45.6.7"} | convertto-json
But then I get this error:
Invoke-RestMethod : {"message":"beginObject() Expecting JSON Array, not a JSON Start of an Object","details":{},"description":"An error occurred parsing the JSON formatted message
body","code":1001,"http_response":{"message":"Invalid syntax for this request was provided","code":400}}
At Z:\Tools\Scripts\PowerShell\RefSetPostExample.ps1:24 char:1
+ Invoke-RestMethod -Method Post -Uri $URI -Body $body -contenttype "ap ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
Thanks in advance for any advice on this.
Thanks to #4c74356b41 's practical advice I found:
http://wahlnetwork.com/2016/02/18/using-powershell-arrays-and-hashtables-with-json-formatting/
The answer was to do this:
$body = #("10.10.50.50","10.50.1.5")| convertto-json
Thank you!