How to use a post request correctly within powershell - powershell

Currently I am trying to work with an API that is utilizing cURL and I am trying to convert it to PowerShell.
Currently the example given by this company is by using cURL is:
$ curl -X POST -u "youruser:yourkey" -H "Content-Type: application/json"
"https://falconapi.crowdstrike.com/detects/entities/summaries/GET/v1" -d
'{"ids": ["ldt:ddaab9931f4a4b90450585d1e748b324:148124137618026"]}'
Right now I am trying to convert this within powershell by using the Invoke-WebRequest method using the following:
Invoke-WebRequest -Method Post -Uri $site -Body -Credential 'whatever credentials' |
ConvertFrom-Json | Select -ExcludeProperty resources
The part I am getting confused on is how to format the -Body request to be something similar to:
'{"ids": ["ldt:ddaab9931f4a4b90450585d1e748b324:148124137618026"]}'
where the LDT part is I am going through an array so instead of the ldt I am trying to call a variable such as $detections, but I am unable to.

You could just create a hash table and convert to json:
-body (#{ids = ($detections)} | ConvertTo-Json)
or if detections is an array you could omit the () around $detections

You aren't able to use a variable because you're using single quoted ' strings, which don't interpret variables or escape sequences. You need to use a double quoted " string for that. Since your string contains double quotes you'd need to escape them with PowerShell's escape character, which is the backtick `.
"{`"ids`": [`"ldt:$detections`"]}"
This likely not what you want though; you probably want to serialize the array into JSON, in which case you should use 4c74356b41's answer; that is: create an object with the values you want and then convert it to JSON at runtime. This is much less error prone.

You could use double quoted strings around the outside of your JSON body and then you are able to include the variable:
Invoke-WebRequest -Method Post -Uri "{'ids': ['ldt:$detections']}" -Body -Credential 'whatever credentials' |
ConvertFrom-Json | Select -ExcludeProperty resources

Related

Output in a different format

I'm hitting an API endpoint for the UniFi Controller.
I run a command to give me devices that do NOT have a specific MAC address.
The command returns 3 mac addresses.
When working with PowerShell, how can you use the 3 mac addresses returned as 3 different items so that I can do a 'foreach' statement on them?
$returnedDevices = $response.data | select mac | where-object {$_.mac -notlike "18:e8:29:4f:0b:33"}
This is what is returned:
mac
---
80:2a:a8:c9:c3:c3
18:e8:29:93:00:d1
18:e8:29:93:6c:85
When I run: $returnedDevices.Count
I get '3'.
So it looks like 3 different values, but if I try to use this in a ForEach statement:
ForEach ($item in $returnedDevices) {
$command = "`{`"cmd`":`"restart`",`"reboot_type`":`"soft`"`,`"mac`":`"$item.mac`"`}"
$response = Invoke-RestMethod -Uri "$devURI" -Method Post -Body $command -ContentType "application/json" -WebSession $session
}
What happens is I get an error because this is what is being sent to the API:
{"cmd":"restart","reboot_type":"soft","mac":"#{mac=80:2a:a8:c9:c3:c3}.mac"}
I would think, it should be:
{"cmd":"restart","reboot_type":"soft","mac":"80:2a:a8:c9:c3:c3}.mac"}
How can I either trim the beginning or, better yet, get the right format?
Also, if I do the following, the output looks like what I would expect:
$item.mac
Output:
80:2a:a8:c9:c3:c3
Thank you,
When you write a variable and its property inside of a string, that property becomes part of the quoted string.
$command = "`{`"cmd`":`"restart`",`"reboot_type`":`"soft`"`,`"mac`":`"$item.mac`"`}"
# vs
$command = "`{`"cmd`":`"restart`",`"reboot_type`":`"soft`"`,`"mac`":`"$($item.mac)`"`}"
1st Command is going to display $item but consider .mac to be part of the regular string. If you need to get the mac out of the variable $item and display it, you have to use the whole thing as a variable... and thats by encapsulating them with $().

Display all content with Invoke-WebRequest

So I decided to start using PowerShell rather than Command Prompt. And I want to run curl. Very different output then discover that curl is an alias to Invoke-WebRequest in PowerShell.
Using PowerShell curl in the same way as real curl, I only get part of the content displayed.
I have seen that I can put the output of PowerShell curl into a variable and then use $variable.Content to display all of the content but that seems extra work over real curl.
Is there an option to show all of the content directly? I can't see one in the help.
Unlike the curl command line utility Invoke-WebRequest returns an object with various properties of which the content of the requested document is just one. You can get the content in a single statement by expanding the property like this:
Invoke-WebRequest 'http://www.example.org/' | Select-Object -Expand Content
or by getting the property value via dot-notation like this:
(Invoke-WebRequest 'http://www.example.org/').Content
Alternatively you could use the Windows port of curl:
& curl.exe 'http://www.example.org/'
Call the program with its extension to distinguish it from the alias curl for Invoke-WebRequest.
Well, if you are bothered with extra typing this is the shortest way to achieve that (well, at least I can think of):
(iwr google.tt).content
Something like this?
$res=Invoke-WebRequest "https://www.google.fr/"
#to view html of body
$res.ParsedHtml.body.innerHTML
#to view text of body
$res.ParsedHtml.body.innerText

Parsing HTML with PowerShell on dynamic sites

Is there a way to parse HTML from http://www.pgatour.com site using Invoke-WebRequest cmdlet? When I try doing this, ParsedHtml does not contain elements that I need (because cmdlet incorrectly parses the page).
I tried getting data from this page by creating IE COM object in PowerShell and it works, but very slow, so I'm wondering if there is another approach using Invoke-WebRequest (or even external parsers).
Thanks!
You could give the HmtlAgilityPack a try to parse the content returned by Invoke-WebRequest. In this scenario, I would use the -UseBasicParsing parameter.
Window 10 64-bit. PowerShell 5.1
Parsing HTML with PowerShell 5.1 on dynamic sites using Invoke-WebRequest and a regex that returns everything between un-nested tags like <html>,<title>,<head>, and <body>. It will take some tweaking for nested tags.
Invoke-WebRequest -Uri http://www.pgatour.com | sc golf.html
(gc -raw golf.html) -match '(<body>)(.*|\n).*?(<\/body>)'
$matches[0]
Everything between <div class="success-message"> and the next </div>
Invoke-WebRequest -Uri http://www.pgatour.com | sc golf.html
(gc -raw golf.html) -match '(<div class="success-message">)(.*?|\n)*(<\/div>)'
$matches[0]
Greedy and lazy quantifiers explained
regex101.com is your friend.

Powershell Invoke-RestMethod incorrect character

I'm using Invoke-RestMethod to get page names from an application I'm using. I notice that when I do a GET on the page it returns the page name like so
This page â is working
However the actual page name is
This page – is working
Here's how my request looks
Invoke-WebRequest -Uri ("https://example.com/rest/api/content/123789") -Method Get -Headers $Credentials -ContentType "application/json; charset=utf-8"
The problem is with the en-dash, does anyone know how I can fix this?
In case of Invoke-WebRequest does not detect responce encoding right, you can use RawContentStream and convert it to needed encoding:
$resp = Invoke-WebRequest -Uri ...
$html=[system.Text.Encoding]::UTF8.GetString($resp.RawContentStream.ToArray());
Invoke-restmethod or invoke-webrequest?
The Invoke-RestMethod cmdlet uses the default decoding on the result of the HttpWebResponse.CharacterSet property.
If that is not set it uses a default encoding of ISO-8859-1 by default (afaik).
I'm assuming your server is sending some wrong charset in the response headers (or dropping it) hence it's beeing decoded wrongly.
Do you know what charset/encoding are sent in your response from your server?
If you're trying the Invoke-webrequest; check your headers in your response like e.g.
$r = invoke-webrequest http://example.com
$r.Headers
If you're dealing with an encoding issue; e.g. your server is not sending the right headers; you can always try to dump the response in a file and read it with a different encoding:
Invoke-WebRequest http://example.com -outfile .\test.txt
$content = get-content .\test.txt -Encoding utf8 -raw
In this case you will no longer be working with the http-response; but it might help you debug/find the encoding issues your looking for.
One line solution (without files):
[system.Text.Encoding]::UTF8.GetString((Invoke-WebRequest "https://www.example.com").RawContentStream.ToArray())

Invoke-WebRequest - issue with special characters in json

I'm trying to send special characters (norwegian) using Invoke-WebRequest to an ASP .NET MVC4 API controller.
My problem is that the json object show up as NULL when received by the controller, if my json data contains characters like Æ Ø Å.
An example of my code:
$text = 'Æ Ø Å'
$jsondata = $text | ConvertTo-Json
Invoke-WebRequest -Method POST -Uri http://contoso.com/create -ContentType 'application/json; charset=utf8' -Body $jsondata
Also when looking in fiddler the characters turn up like the usual weird utf8 boxes.
Sending json data from fiddler to the same API controller works fine
Any advice?
For the Body parameter try this:
... -Body ([System.Text.Encoding]::UTF8.GetBytes($jsondata))
The string in PowerShell is Unicode but you've specified a UTF8 encoding so I think you need to give it some help getting to UTF8.