Issue
I am having trouble creating an automation script to upload CSV files to a webserver using tokens for authentication. Initially, I tried using cURL but received the following message: "LogError : The remote server returned an error: (400) Bad Request". I spent hours trying to troubleshoot the issue but was unsuccessful, so I switched to PowerShell. Unfortunately, I received the same error.
Here is my cURL script:
$file = "c:\folder\file.csv"
$machinetoken = $companySettings.EncryptionToken
curl -Uri https:https://site/upload/files -Method Post -Headers @{"Authorization" = $($machinetoken)} -InFile $file -Verbose
Here is the error message I received from cURL:
LogError : The remote server returned an error: (400) Bad Request.
Additionally, here is the PowerShell script I used:
try {
$response = Invoke-RestMethod -Method 'Post' -Uri $endpoint -Headers $headers -InFile $file
}
catch {
$errorMessage = $_.Exception.Message
if (Get-Member -InputObject $_.Exception -Name 'Response') {
try {
$result = $_.Exception.Response.GetResponseStream()
$reader = New-Object System.IO.StreamReader($result)
$reader.BaseStream.Position = 0
$reader.DiscardBufferedData()
$responseBody = $reader.ReadToEnd();
} catch {
Throw "An error occurred while calling REST method at: $url. Error: $errorMessage. Cannot get more information."
}
}
Throw "An error occurred while calling REST method at: $endpoint. Error: $errorMessage. Response body: $responseBody"
}
And here is the error message I received from PowerShell:
An error occurred while calling REST method at: https://site/upload/files. Message: The remote server returned an error: (400) Bad Request.. Response body: result_code=NOT_MULTIPART
I would greatly appreciate any help with this issue. Thank you!
Solution
I found an answer on Reddit:
"PowerShell 6.1 or later, Invoke-RestMethod has the new -Form parameter that automatically deals with all of the MultipartFormDataContent stuff for you. It also has -SkipCertificateCheck so you don't have to deal with ServicePointManager. It also defaults to using the latest TLS versions, but you also have the -SslProtocol parameter if needed" Read full thread on Reddit
I change my script and upgraded Powershell to version 7.3.4 and it worked!
$machinetoken = "fsdfadfadgadgfdagfgdfgadgfaf"
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", $($machinetoken))
$headers.Add("Content-Type", "multipart/form-data")
$headers.Add("Cookie", "XXXXxxxxXX;xxXXXxxxxXX")
$multipartContent = [System.Net.Http.MultipartFormDataContent]::new()
$multipartFile = $path
$FileStream = [System.IO.FileStream]::new($multipartFile, [System.IO.FileMode]::Open)
$fileHeader = [System.Net.Http.Headers.ContentDispositionHeaderValue]::new("form-data")
$fileHeader.Name = "report_data"
$fileHeader.FileName = "C:\blabla\filename.txt"
$fileContent = [System.Net.Http.StreamContent]::new($FileStream)
$fileContent.Headers.ContentDisposition = $fileHeader
$multipartContent.Add($fileContent)
$body = $multipartContent
$response = Invoke-RestMethod 'https://site/report' -Method 'POST' -Headers $headers -Body $body
$response | ConvertTo-Json
Answered By - Brian Lind Eriksen Answer Checked By - Terry (WPSolving Volunteer)