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!
Related
I am trying to send a message to App Dynamics using 'Invoke-RestMethod' through powershell which is giving below error
Invoke-RestMethod : AppDynamics - Error report HTTP Status 400 - Event
summary is not specifiedtype Status reportmessageEvent summary is not
specifieddescriptionThe request sent by the client was syntactically
incorrect.
I am using below code to send message.
$JSONBody = #{
'#context'= 'http://schema.org/extensions'
'#type'= 'MessageCard'
'title' = 'Incoming Alert Test Message'
'text' = 'xyz'
'eventtype'='CUSTOM'
'customeventtype'='appDcustomevent'
}
$json = ConvertTo-Json $JSONBody -Depth 100
$headers = #{Authorization='Basic '+[Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes('username#account:password'))}
$response = Invoke-RestMethod -Uri 'https://rest api url/events' -Proxy 'proxy url:80' -Method Post -Headers $headers -Body $json -ContentType 'application/json'
Please help me understand how to fix this issue as i have no clue.
Thanks in advance,
Usha.
Your request is missing the "summary" field as per the documentation: https://docs.appdynamics.com/appd/20.x/en/extend-appdynamics/appdynamics-apis/alert-and-respond-api/events-and-action-suppression-api#EventsandActionSuppressionAPI-CreateaCustomEvent
(Every field marked as Mandatory under "Input parameters" table must be included in the request)
Update:
Below is tested as working, seems the JSON version does indeed have issues - so switched to using query params and this works as intended.
$application_id = "<APPLICATION_NAME>"
$summary = "This_is_a_summary"
$severity = "INFO"
$eventtype = "CUSTOM"
$controller = "<CONTROLLER_URL_NO_PROTOCOL>"
$port = "8090"
$protocol = "http"
$account = "<ACCOUNT>"
$username = "<USERNAME>"
$password = "<PASSWORD>"
$controllerEndpoint = "controller/rest/applications/${application_id}/events"
$restURL = "${protocol}://${controller}:${port}/${controllerEndpoint}?severity=${severity}&summary=${summary}&eventtype=${eventtype}"
"$restURL"
$headers = #{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("${username}#${account}:${password}"))}
$response = Invoke-RestMethod -Uri $restURL -Method Post -Headers $headers -Body $JSON -ContentType "application/json"
$response.content
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
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.
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
The following works fine on my machine which does not use a web proxy.
return Invoke-RestMethod
-Uri $server$url
-ContentType $contentType
-Headers $headers
-Method $method
-UseDefaultCredentials
Note: the $server$url is an https address, something like https://somewhere.example.com/api/data
Now I'm trying to get it to work in a corporate environment but I am getting a 401 error.
I think this is because there is a corporate proxy which is defined with a proxy.pac file. I have confirmed I can get to the $server$url URI from Internet Explorer. What do I need to do to get the Invoke-RestMethod command to work using the same settings?
I have tried adding the -proxy parameter
$proxy = [System.Net.WebRequest]::GetSystemWebProxy()
$proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials
return Invoke-RestMethod
-Uri $server$url
-ContentType $contentType
-Headers $headers
-Method $method
-UseDefaultCredentials
-Proxy $proxy
-ProxyUseDefaultCredentials
but the -Proxy parameter is expecting a URI not an IWebProxy object.
The accepted answer got me started. Here's the full version
$headers = #{"X-My-ApiKey"=$apiKey}
$contentType = "application/json"
$proxyUri = [Uri]$null
$proxy = [System.Net.WebRequest]::GetSystemWebProxy()
if ($proxy)
{
$proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials
$proxyUri = $proxy.GetProxy("$server$url")
}
if ("$proxyUri" -ne "$server$url")
{
Write-Host "Using proxy: $proxyUri"
return Invoke-RestMethod -Uri $server$url -ContentType $contentType -Headers $headers -Method $method -UseDefaultCredentials -Proxy $proxyUri -ProxyUseDefaultCredentials
}
else
{
return Invoke-RestMethod -Uri $server$url -ContentType $contentType -Headers $headers -Method $method -UseDefaultCredentials
}
Edit: Once incorrect address is provided the command no longer works and returns the address provided instead of the proxy address..
Do not use this:
Using the code snippet in this, I am able to retrieve the proxy uri from PowerShell as such:
[System.Net.WebRequest]::DefaultWebProxy.GetProxy([uri]("http://www.google.com"))
Use this instead:
[System.Net.WebRequest]::GetSystemWebProxy().GetProxy("http://www.google.com")
It still returns the provided URI (or throws) when the uri is invalid, but once correct uri is provided is starts working again.