How to make a POST request with file content via Powershell - powershell

I want to make a post call with powershell which should contain the file content as body, so I try to use Invoke-Webrequest.
When I make the call like this, there is no data on the server side. I can see that on the server where the HttpServletRequest.getInputStream is null, any idea what is the problem?
$FilePath = '.\foobar.txt'
$fileContent = Get-Content -Path $FilePath -Encoding Byte
Write-host $fileContent
$Response = Invoke-WebRequest -Body $fileContent -Method 'POST' -Uri 'http://myAddress'

tldr: You need to add the Parameter -ContentType "application/octet-stream"
First of all you should replace Get-Content -Path $FilePath -Encoding Byte with [System.IO.File]::ReadAllBytes($FilePath) as it is way faster. This is also the reason why I do not suggest to use the -InFile Parameter as it internaly also uses that slow, inperformant Get-Content Method.
In combination you propably also need to add -ContentType "application/octet-stream" otherwise the Body is not serialised as the raw byte array.
So in the end it should look something like this:
$FilePath = '.\foobar.txt'
$fileContent = [System.IO.File]::ReadAllBytes($FilePath)
$Response = Invoke-WebRequest -Body $fileContent -Method 'POST' -Uri 'http://myAddress' -ContentType 'application/octet-stream'

Related

Trying to use the "SetDeviceName" action with Microsoft Graph

Trying to do a bulk rename of device when they haven't been logged on for a long time.
I have managed to gather the information I need it and pipe it, so it comes out correctly.
But for some reason, I get Bad request and my formating is some how wrong, but can't figure out what. Tried every type of modification to the URI, but no luck.
This should work according to Microsoft's Doc about SetDevicename action
$date = (Get-date (Get-date).adddays(-316) -format "yyy-MM-ddTHH:mm:ssZ")
$devices | where {$_.lastSyncDateTime -le $date} | ForEach-Object {
$newname = "Test-$($_.Devicename)"
$deviceID = "$($_.ID)"
$URI = "https://graph.microsoft.com/beta/deviceManagement/managedDevices/$deviceID/setDeviceName"
$Body = #{ "deviceName" = "$NewName" } | ConvertTo-Json
$Method = "POST"
Invoke-RestMethod -Uri $URI -Method $Method -Headers $appauthToken -body $body -ContentType "application/json"
}
Any Idea what I'm doing wrong?
There is another method of renaming of bulk devices:
Document reference: https://learn.microsoft.com/en-us/mem/intune/remote-actions/device-rename#bulk-rename-devices.

Powershell - Loop through folder, Get Contents and post to SOAP

I am trying to loop through a folder, grab all files, read their contents then post each file content individually to SOAP.
This is how I would do it, but PowerShell returns an error.
Invoke-Webrequest : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.
Below is my code:
$dataAPI = Get-ChildItem 'C:\Users\..\Output'
$uri = 'http://server-name.com:8080/name/name2'
ForEach ($Item in $dataAPI) {
Get-Content $Item.FullName | Invoke-Webrequest -Headers #{"Content-Type" = "text/xml;charset=UTF-8"; "SOAPAction" = "http://server-name.com:8080/name/name2"} -Method 'POST' -Body $dataAPI -Uri $uri -UseDefaultCredential
}
I am not really sure where I should place the Invoke-WebRequest...
Any help would be appreciated. Thanks.
Continuing from my comments,
Add switch -Raw to the Get-Content call to receive a single multiline string instead of an array of lines
Add switch -File to the Get-ChildItem call to ensure you will only deal with files in the loop, not directories too
Try
# if all files you need have a common extension, add `-Filter '*.xml'` to below line
# '*.xml' is just an example here..
$files = Get-ChildItem -Path 'C:\Users\Gabriel\Output' -File
$uri = 'http://server-name.com:8080/name/name2'
$header = #{"Content-Type" = "text/xml;charset=UTF-8"; "SOAPAction" = "http://server-name.com:8080/name/name2"}
foreach ($Item in $files) {
$content = Get-Content $Item.FullName -Raw
Invoke-Webrequest -Headers $header -Method 'POST' -Body $content -Uri $uri -UseDefaultCredential
}

Exporting Powershell REST API results as CSV

I'm currently use the following Powershell script as an API call using REST to retrieve table data from a vendor, which appears to be in JSON format:
$uri = "https://www.SomeWebsite.com/api/orders"
$headers = #{
'Content-Type' = 'application/json'
'Authorization' = 'Bearer <MyTokenID>'
'Accept'= 'application/json'
}
Invoke-RestMethod -Uri $uri -Method GET -Headers $headers -Body $body
The script works, and output as such in Powershell:
data
----
{#{type=appointments; id=1234; attributes=; links=; relationships=}, #{type=appointments; id=1235; attributes=; links=; relationships=}, #{type=appointments; i...
I need the ability to export this as a CSV file.
How can I incorporate anexport-CSV CMDLET (something like below) to have it work with the above syntax? (Preferably ALL Columns/Headers)
Select ID, Status | Export-Csv -Path "filename.csv" -NoTypeInformation
Your Invoke-RestMethod outputs an object with a data property. The data property contains the objects you want to reference. So you must expand that property first.
Invoke-RestMethod -Uri $uri -Method GET -Headers $headers -Body $body |
Select-Object -ExpandProperty data |
Select-Object id,status |
Export-Csv filename.csv -NoTypeInformation

Netbox secrets with PowerShell

I am trying to access secrets in Netbox like in this example
https://netbox.readthedocs.io/en/latest/api/working-with-secrets/
but using Powershell but I seem to have hit a brick wall.
Here is my code:
Add-Type -AssemblyName System.Web
$Hdrs = #{}
$Hdrs.Add("Authorization","Token fafcaea339cf926c0d79tokenf916aeec2d18bdd")
$Hdrs.Add("Accept","application/json; indent=4")
$body = Get-Content 'c:\key\private.txt'
$body = [System.Web.HttpUtility]::UrlEncode($body)
Invoke-RestMethod -Method post -Uri "http://netbox.et/api/secrets/get-session-key/" -Headers $Hdrs -body $body
I just get the error
Invoke-RestMethod : Private key was not provided.
I'm pretty sure the issue is with how I am forming the request, however, I don't know enough about curl to know what '--data' do and how that would look in Powershell. Any help would be most appreciated.
OK, there were multiple issues. The first that I need to pass the private key as an object with two clear fields like I am the header and the other was I had URL encoded it by defining it in the header and then used a function to URL encode it again, which in turn made the private key invalid.
This is the solution
Add-Type -AssemblyName System.Web
$Hdrs = #{}
$body = #{}
$Hdrs.Add("Authorization","Token fafcaea339cf926c0d7977e3ff916aeec2d18bdd")
$Hdrs.Add("Accept","application/json; indent=4")
$Hdrs.Add("Content-Type","application/x-www-form-urlencoded")
$Pkey = Get-Content -raw 'c:\key\private.txt'
$body.add("private_key",$PKey)
Invoke-RestMethod -Method post -Uri "http://netbox.net/api/secrets/get-session-key/" -Headers $Hdrs -Body $body

Using powershell's Invoke-RestMethod cmdlet is only returning the word "success" as a result

I have written 2 scripts. One in python and one in powershell. Python is able to call a rest api and is returned the string "JSESSIONID=8kfv0fi1bc84gtw2xvnqsrt4;Path=/;Secure;HttpOnly ". When I use the following code in powershell, it returns "success". What am I doing wrong?
$getEncCode = "Er6TmdhXn09Y9C1I"
$dataPart1 = #{EncCode=$getEncCode}
$dataPart = $dataPart1 | ConvertTo-Json
$uri = "https://10.164.42.77:8092/getEnc/2252953/login"
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
$result = Invoke-RestMethod -Method Post -Body $dataPart -uri $uri -ContentType "application/json"
Write-Host $result
Write-Host $result uses the $result.ToString() method to display that object as a string.
Likely there is more data there to show. Simply remove Write-Host to see it. Or do something like Get-Member -InputObject $result to see all immediate properties, methods etc.
Have a look at Printing object properties in Powershell to see other ways to deal with this.