Invoke-RestMethod issue with plus symbol in URL

Bill C 1 Reputation point
2020-07-30T22:05:57.073+00:00

I have an API that I access from a linux server now but it is being decommissioned so I am converting my API calls to windows. I use this call in linux and it works fine:

curl "https://site.api.opsramp.com/api/v2/tenants/client/alerts/search?pageNo=1&pageSize=5&isDescendingOrder=true&queryString=metrics:Agent%20Status+states:Critical" -H "Content-Type: application/json" -H "Accept: application/json" -H "Authorization: Bearer ${dlAccessToken}"

When I switched to PowerShell, this request works (note, it has only "&queryString=metrics:Agent%20Status" at the end of the URI):

$orHeaders = @{
    "Accept"="application/json"
    "Authorization"="Bearer $orAccessToken"
}
$orRestResponse = Invoke-RestMethod -Uri "https://site.api.opsramp.com/api/v2/tenants/client/alerts/search?pageNo=1&pageSize=5&isDescendingOrder=true&queryString=metrics:Agent%20Status" -ContentType application/json -Headers $orHeaders

Results:

totalResults : 1739
orderBy : ts
pageNo : 1
pageSize : 5
totalPages : 348
nextPage : True
nextPageNo : 2
previousPageNo : 0
descendingOrder : True

This request works as well (note, it has only "&queryString=states:Critical" at the end of the URI):

$orHeaders = @{
    "Accept"="application/json"
    "Authorization"="Bearer $orAccessToken"
}
$orRestResponse = Invoke-RestMethod -Uri "https://site.api.opsramp.com/api/v2/tenants/client/alerts/search?pageNo=1&pageSize=5&isDescendingOrder=true&queryString=states:Critical" -ContentType application/json -Headers $orHeaders

Results:

totalResults : 930
orderBy : ts
pageNo : 1
pageSize : 5
totalPages : 186
nextPage : True
nextPageNo : 2
previousPageNo : 0
descendingOrder : True

But when I try to join the 2 search criteria like I had in linux (now it has &queryString=metrics:Agent%20Status+states:Critical at the end of the URI), it returns no results every time. It doesn't break with an error, it just returns 0 results. But due to the 2 above requests working, that leads me to believe is the + symbol that is used to join 2 queryStrings in the URI.

$orHeaders = @{
    "Accept"="application/json"
    "Authorization"="Bearer $orAccessToken"
}
$orRestResponse = Invoke-RestMethod -Uri "https://site.api.opsramp.com/api/v2/tenants/client/alerts/search?pageNo=1&pageSize=5&isDescendingOrder=true&queryString=metrics:Agent%20Status+states:Critical" -ContentType application/json -Headers $orHeaders

Results

results : {}
totalResults : 0
pageNo : 1
pageSize : 5
totalPages : 0
nextPage : False
descendingOrder : False

I was thinking that PowerShell may be reading the + symbol as a special character so I tried escaping it with the `, I tried putting it in apostrophes instead of quotes, and I tried putting it in a variable, all of which were unsuccessful. I did output what the variable had stored, and the text looks correct:

https://site.api.opsramp.com/api/v2/tenants/client/alerts/search?pageNo=1&pageSize=5&isDescendingOrder=true&queryString=metrics:Agent%20Status+states:Critical

Thank you for any suggestions you may have.

Windows Server PowerShell
Windows Server PowerShell
Windows Server: A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.PowerShell: A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
5,446 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Rich Matheisen 45,596 Reputation points
    2020-08-02T20:09:16.913+00:00

    If you suspect the data part of the URI is causing a problem due to an un-escaped character, you could try encoding both parts of the URI:

    $uri = "https://site.api.opsramp.com/api/v2/tenants/client/alerts/search?"
    
    $EscapedUri=[uri]::EscapeUriString($uri)
    
    $data = "pageNo=1&pageSize=5&isDescendingOrder=true&queryString=metrics:Agent Status+states:Critical"
    $EscapedData=[uri]::EscapeDataString($data)
    
    $all = $EscapedUri + $EscapedData
    

    Whether that's your problem or not, I don't really know. In situations like this, where you don't know what the problem is, I've always found that getting a good look at he interaction between the client and server is a good starting point. For that, I'd suggest using a tool like "Fiddler".

    Another approach might be to use Invoke-WebRequest and see if the JSON is correctly formed in the result. It wouldn't be the first time that a minor discrepancy that is accepted by one system if flagged as a problem by another. If you can grab the JSON from the result you can use one of the JSON verifiers on the web to see it passes muster.

    I'm no expert on this topic, though.

    1 person found this answer helpful.
    0 comments No comments