Post to json rest API from powershell - json

Hi can someone tell me where i'm going wrong here, i get the following error executing an API call from powershell. I have tried to format the body i many ways but cannot get it to work.
Invoke-RestMEthod : Cannot send a content-body with this verb-type.
At line:7 char:20
+ ... sponseKan = Invoke-RestMEthod -Uri $kanboardserver -ContentType "app ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Invoke-RestMethod], ProtocolViolationException
+ FullyQualifiedErrorId : System.Net.ProtocolViolationException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
My Code;
$headersKan = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" -ErrorAction Stop
$headersKan.Add("X-API-Auth", "jsonrpc:$kanboardtoken")
$bodyKan = #{jsonrpc = "2.0"
id = "1"
method = "getAllProjects"
} | ConvertTo-Json
$responseKan = Invoke-RestMEthod -Uri $kanboardserver -ContentType "application/json" -Headers $headersKan -Body $bodyKan -ErrorAction Stop
Write-Host $responseKan

The default http verb is GET which does not allow a body/payload. Pass POST as method argument and do not json-serialize the body yourself.

Related

PowerShell JSON Headers not Converting correctly

I am using an API REST call, but the problem is that it for some reason is not passing the header value correctly. I am getting an error about it not converting from "System.String" to "System.Collections.IDictionary".
The code is:
$Headers = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]'
$Headers.Add('X-CENTRIFY-NATIVE-CLIENT', 'true')
$Headers.Add('Content-Type', 'application/json')
$Body = #{
TenantId = 'ID'
User = 'cloudadmin#andrew1.com'
Version = '1.0'
}
#$wr = Invoke-WebRequest -Method Post -Uri $url -Headers $Headers -Body $Body -Verbose
Invoke-RestMethod -Uri "https://uri/Security/StartAuthentication" -Method Post -Headers ($Headers | ConvertTo-Json -Compress) -UseBasicParsing -Body $Body
But when I execute I get this error (FQID):
Invoke-RestMethod : Cannot bind parameter 'Headers'. Cannot convert the "{
"X-CENTRIFY-NATIVE-CLIENT": "true",
"Content-Type": "application/json"
}" value of type "System.String" to type "System.Collections.IDictionary".
At line:31 char:109
+ ... tication" -Method Post -Headers ($Headers1 | ConvertTo-Json) -UseBas ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Invoke-RestMethod], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
I have tried my headers being like this as well:
$headers = #{
'Content-Type'= 'application/json'
'X-CENTRIFY-NATIVE-CLIENT'= 'true'
}
But I still get that same error. It is odd that it keeps complaining about this reference; This library is not native to PoSH. Is there a DLL I should load or is there a better way to go about this?
The -Headers parameter expects a dictionary, not a json object.
Pass $Headers directly:
$uri = "https://uri/Security/StartAuthentication"
Invoke-RestMethod -Uri $uri -Method Post -Headers $Headers -UseBasicParsing -Body $Body
You can inspect parameter details with Get-Help:
PS > Get-Help Invoke-WebRequest -Parameter Headers
-Headers <IDictionary>
Required? false
Position? Named
Accept pipeline input? false
Parameter set name (All)
Aliases None
Dynamic? false
I took the json conversion out of the header on your invoke restmethod. That part will need to be done on your payload $Body. Give this a try.
$Headers = #{}
$Headers.Add('X-CENTRIFY-NATIVE-CLIENT', 'true')
$Headers.Add('Content-Type', 'application/json')
$Body = #{
TenantId = 'ID'
User = 'cloudadmin#andrew1.com'
Version = '1.0'
}
$Body = ($Body | ConvertTo-Json)
#$wr = Invoke-WebRequest -Method Post -Uri $url -Headers $Headers -Body $Body -Verbose
Invoke-RestMethod -Uri "https://uri/Security/StartAuthentication" -Method Post -Headers $Headers -UseBasicParsing -Body $Body

Saving file as .pem from powershell 5.1 with encoding as utf8noBOM and reading it with openssl throws error

I'm trying to upload the .pem file to an API using powershell, we have to convert it to JSON format and then post it. Well, this works fine by using the below snippet
$t = Get-Content -Delimiter "`n" -Path 'xxxxxx.pem'
$a = [pscustomobject]#{"certificate" = "$($t)"
"description" = ""
"extension" = ".pem"}
$body = $a | convertto-json
$web = Invoke-WebRequest -Uri $url -ContentType "application/json" -Headers $headers -Body $body -Method POST
While retrieving, i'm using the below snippet
$web = Invoke-WebRequest -Uri $url -ContentType "application/json" -Headers $headers
$temp = $web.Content | ConvertFrom-Json
$cert = $temp.data.certificate
$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
[System.IO.File]::WriteAllLines("*****.pem", $cert, $Utf8NoBomEncoding)
Then I pass the file created using the above snippet to openssl, as follows
openssl.exe x509 -in "*****.pem" -checkend 129600
which is throwing me the following error,
openssl.exe : unable to load certificate
At line:1 char:1
+ openssl.exe x509 -in "******.pem" -checkend 129600
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (unable to load certificate:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
14660:error:0909006C:PEM routines:get_name:no start line:crypto\pem\pem_lib.c:745:Expecting: TRUSTED CERTIFICATE
I'm baffled here, dont know what did i get wrong.
Cause both files, the orginal .pem file and the one created from PS are utf-8 encoded and couldn't see any BOM chars in notepad++.

ConverFrom-JSON Error: Invalid JSON Primitive || PowerShell PoweBi Embeded Token Generator Code

ConverFrom-JSON : Invalid JSON Primitive error, primitive is not being recognized by PowerShell for some reason.
I need to generate PowerBi Embedded Tokens for my PowerBi reports. I can log in to my Microsoft account with out no problem and can invoke the report as well. At the end code supposed to return a embedded token to me, but I encounter with error :
ConvertFrom-Json : Invalid JSON primitive: .
At line:13 char:21
+ $json = $response | ConvertFrom-Json
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [ConvertFrom-Json], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand
I have already tried the Out-String and Raw with Get-Content method, they did not work either.
CODE:
//Sign in with a user that has admin rights to App Workspace
Login-PowerBI
//Regular Report
$url = "https://app.powerbi.com/reportEmbed?reportId=5515f33b-c114-41c9-a925-d1f85c323dab&groupId=e53e4fcd-16f8-46ef-8740-8e7167562ceb&autoAuth=true&ctid=c760270c-f3da-4cfa-9737-03808ef5579f/GenerateToken"
$body = "{ 'accessLevel': 'View' }"
$response = Invoke-PowerBIRestMethod -Url $url -Body $body -Method Post
$response
$json = $response | ConvertFrom-Json
$json.token
It should return a huge paragraph of gibberish code, which will be my report's embedded token.
$url is incorrect - need to call api.powerbi.com
https://api.powerbi.com/v1.0/myorg/groups/{GroupID}/reports/{ReportID}/GenerateToken
try
$url = "https://api.powerbi.com/v1.0/myorg/groups/e53e4fcd-16f8-46ef-8740-8e7167562ceb/reports/5515f33b-c114-41c9-a925-d1f85c323dab/GenerateToken"

Manipulate json and send it into web request using Powershell

I'm trying to manipulate a json object and send it as content into the body of a put / post web request. The source of my json is a file on my disk.
This is my Powershell script:
$urlBase = 'https://mysite.myapp.com/service/api/Item/'
$myJson = (Get-Content 'file.json' | ConvertFrom-JSON)
# Then I manipulate my object
$id = $myJson.id
$myJson.version = '1.2.3.4'
# Request
$response = Invoke-RestMethod -Uri ($urlBase + $id) -Method Put -Body $myJson -ContentType 'application/json' -Headers $hdrs
When I execute my script y get this error message:
Invoke-RestMethod : The remote server returned an error: (400) Bad Request.
At line:18 char:17
+ ... $response = Invoke-RestMethod -Uri ($urlBase + $id) -Method Put -Body ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
If I change my $myJson asignment for this the request works fine...
$myJson = Get-Content 'file.json'
... , but then I can't manipulate my json before send it.
Edited:
If I try to convert back using ConvertTo-Json I get the same error:
$convertedBack = $myJson | ConvertTo-Json
# Request
$response = Invoke-RestMethod -Uri ($urlBase + $id) -Method Put -Body $convertedBack -ContentType 'application/json' -Headers $hdrs
As pointed out in the comments: you need to convert your object back to JSON using the ConvertTo-Json cmdlet.
I see that you've tried that now and had the same problem. So I ask you this: is the value of $convertedBack exactly what you expected? Dump it to file and check!
The reason I am suspicious of this detail is that ConvertTo-Json has a little gotcha in it. Specifically the -Depth parameter which can cause some data loss.
-Depth
Specifies how many levels of contained objects are included in the JSON representation. The default value is 2.
Example Without -Depth
$basicJsonObject = #"
{
"name": "George",
"properties": {
"mood": "jovial",
"coffee": {
"hasCoffee": true,
"mugContents": {
"milk": false,
"doubleShot": true
}
}
}
}
"#
$psObject = ConvertFrom-Json -InputObject $basicJsonObject
Write-Host "Freshly Imported"
Write-Host "DoubleShot = $($psObject.properties.coffee.mugContents.doubleShot)"
$convertedBack = ConvertTo-Json -InputObject $psObject
$reConverted = ConvertFrom-Json -InputObject $convertedBack
Write-Host "Re-Converted"
Write-Host "DoubleShot = $($reConverted.properties.coffee.mugContents.doubleShot)"
Results
Freshly Imported
DoubleShot = True
Re-Converted
DoubleShot =
Example With -Depth
Change one line of code:
$convertedBack = ConvertTo-Json -InputObject $psObject -Depth 5
Results
Freshly Imported
DoubleShot = True
Re-Converted
DoubleShot = True
Note how the new results include the value from the $reConverted variable. This is because the data is not lost further upstream!

How to POST in powershell to canvas LMS

I am currently making an API for an university. The purpose of this project to to look at every course and check if it contains a certain module and if not, add one in. Seems fairly simple enough, but the thing that is making the project complicated is on learning the syntax on to actually do it! I am writing this code in powershell and I have tried to use curl and invoke web request. I tried following canvas' documentation, but I cannot get it. Here are two instances I have, can you please show me how to properly format this.
######this is the first way I tried it and the error I get Invoke-WebRequest : {"message":"missing module parameter"}
$temp2=($mainURL+$course.ID+"/modules"+$securityToken)
$reply = curl -Uri $temp2 -Method Post -Body '{"module[name]"="Getting started","module[position]"="1"}'
#######
#########This is the second way I've tried and the error I get Invoke-WebRequest : The remote server returned an error: (422) Unprocessable Entity.
$url="https://University.instructure.com/api/v1/courses/1371/modules?access_token=abc123"
$body= "{'module[name]'='Getting started,'module[position]'=1}"
Invoke-WebRequest -Uri $url -ContentType "application/json" -Method Post -Body $body
#########
Documentation from the website https://canvas.instructure.com/doc/api/index.html
UPDATE 5-26-2016
I have figured out how to properly format the body for the message. Now I am getting the error message
$header = #{"Authorization"="Bearer "+ $security_token}
$body= '{"module[name]":"Getting started","module[position]":"1"}'
$curlly=Invoke-WebRequest -Headers $header -Body $body -Method Post -ContentType "application/json" -Uri ($url_main+"courses/1371/modules")
$module = ConvertFrom-Json $curlly.Content
curl : Invalid URI: The hostname could not be parsed.
At line:1 char:1
+ curl
+ ~~~~
+ CategoryInfo : NotSpecified: (:) [Invoke-WebRequest], UriFormatException
+ FullyQualifiedErrorId : System.UriFormatException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
I really do not know what to do at this point any guidance will be appreciated at this point.
After a week of fiddling around with the actual JSON format, I took out the content type on the Invoke-WebRequest to see if the server would be able to just guess the format. It worked!