Powershell how to get the result code from REST - powershell

I'm sending a POST request with ID/password and I need to get back a respond token, how can I get it and save it for later use in the script?
$loginUrl = "https://some-ip"
$params = #{
"username"="$username"
"password"="$password"
}
Invoke-WebRequest -Uri $loginUrl -Method POST -Body ($params|ConvertTo-Json) -ContentType "application/json"

Following your input:
$url = "https://some-ip"
$params = #{
"username" = $username
"password" = $password
} | ConvertTo-Json
$apiReturn = Invoke-RestMethod -Uri $url -Method POST -Body $params -ContentType "application/json"
$apiReturn can then be used as response.
Furthermore, you can use the SessionVariable parameter of Invoke-RestMethod.
$apiReturn = Invoke-RestMethod -Uri $url -Method POST -Body $params -ContentType "application/json" -SessionVariable sessionToken
$sessionToken.Headers.Add('Authorization', $apiReturn)
$sessionToken.Headers.Add('Content-Type', 'application/json')
In this scenario, you add the response token to 'Authorization' and forward the whole token to your subsequent API calls. Like this you only need to add $sessionToken and Content-Type for example is already provided.
Invoke-RestMethod -Method Post -Uri $url -WebSession $sessionToken
You can add more parameters to your Header in case it is required.

Related

Powershell Invoke-RestMethod with body begins from array

I have a web server that responds to a request https://localhost/GetUpdateInfo with a body [{"ipAddress": "10.200.2.55"}]
In postman its Work but in powershell i can`t do this because body begins from array.
When i do exmple code:
$Url = "https://localhost/GetUpdateInfo"
$Body = #(#{
ipAddress = "10.200.2.55"
})
$jsonBody = ConvertTo-Json -InputObject $Body
Invoke-RestMethod -Method 'Post' -Uri $url -Body $jsonBody
i hve error: Invoke-RestMethod : Block length does not match with its complement.
The content type of all POST requests is application/x-www-form-urlencoded unless specified.
Add -ContentType application/json to your last line call so your json is sent correctly.
Invoke-RestMethod -Method 'Post' -Uri $url -Body $jsonBody -ContentType 'application/json'

Invoke-RestMethod Get Request with Query Parameters

I was tasked with spinning up a script for a client which relied on a basic 'GET' request to an API which returned a JSON object which I used info from that to make subsequent calls. This worked great but requirements changed and now I need to send the request with some parameters.
Did some testing in postman and the call works great when I add the query parameters at the end of the Uri (ie. https://test.com/?type=image) but when I try to alter the Uri in the Invoke-WebRequest I'm getting a 'Invoke-RestMethod : Invalid or expired token' error. When I take out the parameters the it works as expected, just with incorrect data.
I have also tried turning the query parameters into a hashtable and as json, and sending it as the body but still get the same error.
I'm at the end of my rope and any insight is appreciated.
what works
$baseUrl = 'https://test.com/api/v2/'
$method = 'GET'
$auth = Get-PSAuthorizationString -Uri $baseUrl -OauthConsumerKey $oauth_consumer_key -OauthConsumerSecret $oauth_consumer_secret -OauthAccessToken $oauth_token -OauthAccessTokenSecret $oauth_token_secret
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Content-Type", "application/json")
$headers.Add("Authorization", $auth)
$responses = Invoke-RestMethod -Method $method -Headers $headers -Uri $baseUrl
what breaks it
$baseUrl = 'https://test.com/api/v2/?type=image'
$responses = Invoke-RestMethod -Method $method -Headers $headers -Uri $baseUrl
$body = #{}
$body['type']="image"
$responses = Invoke-RestMethod -Method $method -Headers $headers -Uri $baseUrl -body $body
Looks like you are inadvertently using $baseUrl in 2 different places, when requesting your token and when invoking your web request.
From your error message, I guess the authorization service does not tolerate the extra parameter.
Try this simple change:
$authUrl = 'https://test.com/api/v2/'
$baseUrl = 'https://test.com/api/v2/?type=image'
$method = 'GET'
$auth = Get-PSAuthorizationString -Uri $authUrl -OauthConsumerKey $oauth_consumer_key -OauthConsumerSecret $oauth_consumer_secret -OauthAccessToken $oauth_token -OauthAccessTokenSecret $oauth_token_secret
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Content-Type", "application/json")
$headers.Add("Authorization", $auth)
$responses = Invoke-RestMethod -Method $method -Headers $headers -Uri $baseUrl
Hope this helps!

graph api assign manager

I'm trying to assign the manager to a user in AAD the documentation says
PUT /users/{id}/manager/$ref
but i'm not sure what to feed the $ref variable. I've tried UPN and the ID, but I keep getting
The remote server returned an error: (400) Bad Request.
Here is how i'm trying to put the manager info, but clearly i'm not doing it right or I can't read the documentation from here
$Header = #{
Authorization = "$($Request.token_type) $($Request.access_token)"
}
$bodyProcess = #{
id= "string aa9999a1-1111-11a2-abab-asfdas32"
}
$body = $bodyProcess | ConvertTo-Json
$Uri = "https://graph.microsoft.com/v1.0/users/4d5f6c5a-0e69-40b6-a86d-e825582add50/manager/$ref"
$UserData = Invoke-RestMethod -Uri $Uri -Headers $Header -Method PUT -ContentType "application/json" -Body $Body
Any help would be greatly appreciated.
thanks,
Here is the full script that works for me.
$Header = #{
Authorization = "$($Request.token_type) $($Request.access_token)"
}
$bodyProcess = #{
"#odata.id"= "https://graph.microsoft.com/v1.0/users/aa9999a1-1111-11a2-abab-asfdas32"
}
$body = $bodyProcess | ConvertTo-Json
$Uri = 'https://graph.microsoft.com/v1.0/users/4d5f6c5a-0e69-40b6-a86d-e825582add50/manager/$ref'
Invoke-RestMethod -Uri $Uri -Headers $Header -Method PUT -ContentType "application/json" -Body $Body

Invoke-WebRequest -Method 'POST' with -ContentType 'application/json' Fails

When using:
$body = #{
Manager = "spmigrationuser#contoso.com" #$item.PMEmail
Name = "some name"
Number = "Some number"
Practice = "Some Practice"
}
$response = Invoke-RestMethod -Method Post -Uri $Url -Body $body -ContentType 'application/json' # -Headers $Headers
Or
$response = Invoke-WebRequest -Method 'POST' -Uri $Url -Body $body -ContentType 'application/json' # -Headers $Headers
Neither ContentType 'application/json'
Nor
$Headers = #{'Content-Type' = 'application/json' }
-Headers $Headers
Works
The error is always:
"Invoke-WebRequest : {"error":{"code":"InvalidRequestContent","message":"The request content is not valid and could not be deserialized: 'Error parsing NaN value. Path '', line 1, position 1.'."}}"
The same call works in Postman
I am using PS 5.1 and I must have -ContentType 'application/json' otherwise PS works but the service fails
What can be the issue?
I agree with NickSalacious. Your issue is that you are not sending JSON.
If you are using Postman and just starting to do API in PowerShell. Postman has a "Code" Link in the top right hand corner of the request. Just below and to the right of the Send button. In there you can select PowerShell. This will give you a good basis to see how the same request could be ran in PowerShell.
Postman would turn your body into this:
$body = "{`n `"Manager`": `"spmigrationuser#contoso.com`",`n `"Name`": `"some name`",`n `"Number`": `"Some number`",`n `"Practice`": `"Some Practice`"`n}"
This is not the easiest to work with and to read. Learning and using ConvertTo-Json is going to help a lot more in the long run.
*Edit: Also look at Invoke-RestMethod and Invoke-WebRequest. They behave differently and sometimes one will be better than the other.
*Edit2: Figured I would put an example of another way to do it.
$request = #{
Uri = 'http://YourURI.Here'
Headers = #{ 'Authorization' = $token
'AnotherHeader?' = 'Sure'}
Method = 'POST'
Body = '{
"Manager": $item.PMEmail,
"Name": "some name",
"Number": "Some number",
"Practice": "Some Practice"
}'
ContentType = 'application/json'
}
$response = Invoke-RestMethod #request
The API requires that the body be a JSON string. You can do a simple conversion (using ConvertTo-Json) in your Invoke-RestMethod command and set the content type accordingly.
Invoke-RestMethod -Method POST -Uri $uri -Header $header -Body ($body | ConvertTo-Json) -ContentType 'application/json'
Sorry I bothered all of you.
I tested on another computer and it works fine.

How do I access the value of a field returned by a Restful API

I have a very basic requirement to call a RESTful API. I am currently on a Windows 2012 R2 server using version 4 of PowerShell.
Here is my code:
$logon = #{
username = 'blah'
password='blah'
}
$body = $logon | ConvertTo-Json
$URI = 'https://URL/Logon'
Invoke-WebRequest -URI $URI -Method POST -Body $body -ContentType 'application/json' -Verbose
I get the following result:
{"LogonResult":"blahblahblah"}
How do I extract just the logon token to reuse as a variable? I've already put a variable at the beginning of the command:
$token = (Invoke-WebRequest -URI $URI -Method POST -Body $body -ContentType 'application/json' -Verbose).content
This returns the entire result, not just the token. How do I get just the token as a result?
You can get the value of the returned LogonResult property as follows:
$token = ((Invoke-WebRequest -URI $URI -Method POST -Body $body -ContentType 'application/json' -Verbose).content | ConvertFrom-JSON).LogonResult
Or you simplify this by using Invoke-RestMethod as this returns just the content and converts it to a PSObject automatically:
$token = (Invoke-RestMethod -URI $URI -Method POST -Body $body -ContentType 'application/json' -Verbose).LogonResult