Invoke-RestMethod uploading CSV in ServiceNow - powershell

I tried many ways of uploading a CSV file to ServiceNow using PowerShell via Invoke-RestMethod and Invoke-WebRequest; however, I have hit a wall. When I call the functions, I receive the following error:
"Invoke-RestMethod : The remote server returned an error: (405) Method Not Allowed."
"Invoke-WebRequest : The remote server returned an error: (405) Method Not Allowed."
I have tried the code below:
Attempt 1)
$Headers = #{'Auth_token'=$envCred};
$FileContent = [IO.File]::ReadAllText('C:\temp\test.csv');
$Fields = #{'uploadFile'=$FileContent};
Invoke-WebRequest -Uri $Uri -ContentType 'multipart/form-data' -Method Post -Headers $Headers -Body $Fields;
Attempt 2)
Invoke-RestMethod -Method Post -Uri $uri -Credential $envCred -ContentType 'multipart/form-data -InFile "C:\temp\test.csv" '
I know for a fact that the API is working, because after I call:
Invoke-RestMethod -Method 'get' -Uri $uri -Credential $snCred -body $body it returns the proper information.
I also tried the [-Method Patch] with the following: "Invoke-RestMethod -Uri $uri -Credential $snCred -Method Patch -ContentType 'text/csv' -InFile "C:\temp\test.csv" - Also tried with the -ContentType 'multipart/form-data' - I get the following error: "Invoke-RestMethod : The remote server returned an error: (415) Unsupported Media Type."
Is there another way or uploading CSV file(s) in PowerShell using the Invoke-RestMethod or Invoke-WebRequest?
Solution:
I realized that I had a typo with my URI, after fixing it, it worked! Sorry for the inconvenience.

It's unclear what endpoint you were using, however, here's an example from the docs
curl "https://instance.service-now.com/api/now/attachment/upload" \
--request POST \
--header "Accept:application/json"
--user 'admin':'admin'"\
--header "Content-Type:multipart/form-data"
-F 'table_name=incident' -F 'table_sys_id=d71f7935c0a8016700802b64c67c11c6' -F 'encryption_context=undefined'-F 'uploadFile=# location of the file on file system'

Related

Upload file to API endpoint with PowerShell using multipart/form-data

This curl command works:
curl -v -X POST https://subdomain.playvox.com/api/v1/files/upload?context=quality -H "Content-Type: multipart/form-data" -u [username]:[password] -F file=#c:\path\to\file.wav
But I am unable to perform the same thing in PowerShell using the Invoke-RestMethod cmdlet. Here's my attempt:
$file_contents = [System.IO.File]::ReadAllBytes($($file_path))
Invoke-RestMethod -Uri "https://subdomains.playvox.com/api/v1/files/upload?context=quality" -Method Post -ContentType "multipart/form-data" -Headers #{ "Authorization" = "Basic $($playvox_base64_auth)" } -Body #{ file = $file_contents }
When run the API responds with invalid_param, "file" is required. However I confirmed the call to ReadAllBytes succeeds and gives back the raw file data. It seems like PowerShell is not sending the request body in the right format? I've looked at several other answers here and documentation online and nothing I found has worked.
Discovered there is a -Form parameter in Powershell 6 and later. I updated my powershell and used the following instead:
$file_contents = Get-Item $file_path
Invoke-RestMethod -Uri "https://subdomains.playvox.com/api/v1/files/upload?context=quality" -Method Post -ContentType "multipart/form-data" -Headers #{ "Authorization" = "Basic $($playvox_base64_auth)" } -Form #{ file = $file_contents }
And it worked.

How to Submit Timestamp Request to RFC 3161 Timestamp Server with Powershell

How would one submit a timestamp request to a RFC 3161 Timestamp Server using PowerShell's Invoke-WebRequest?
First, I create the timestamp request:
openssl ts -query -data message.txt -cert -sha256 -no_nonce -out ts_test_msg_sha256.tsq
Then I can use this curl command to submit it to the Timestamp server. This is confirmed to work.
curl -k -H "Content-Type: application/timestamp-query" -H "Host:timestamp.digicert.com" --data-binary #ts_test_msg_sha256.tsq http://timestamp.digicert.com > ts_test_msg_sha256.tsr
I am trying to do the same thing in PowerShell, but it isnt working. This is the PowerShell command I have tried:
Invoke-WebRequest -uri http://timestamp.digicert.com -Headers #{'Host' = 'timestamp.digicert.com'; 'Content-Type' = 'application/timestamp-query'} -body "ts_test_msg_sha256.tsq" -method POST > "ts_test_msg_sha256.tsr"
And I get this error:
Invoke-WebRequest : The remote server returned an error: (404) Not Found.
What am I doing wrong? As I understand it, the PowerShell command should be the exact same as the curl command.
EDIT: The final command I used was:
Invoke-WebRequest -uri http://timestamp.digicert.com -Headers #{'Host' = 'timestamp.digicert.com'; 'Content-Type' = 'application/timestamp-query'} -infile "ts_test_msg_sha256.tsq" -method POST -outfile ts_test_msg_sha256.tsr | Out-Null
The TS server returns 404 in response to incorrect requests.
The proper request is
$R = Invoke-WebRequest -uri http://timestamp.digicert.com/ -ContentType 'application/timestamp-query' -InFile "ts_test_msg_sha256.tsq" -method POST
Please note -ContentType and -InFile parameters.
The response is saved in $R variable. To write the raw response body to a binary file:
if ($R.StatusCode -eq 200) {
Set-Content ts_test_msg_sha256.tsr -Value $R.Content -AsByteStream;
echo "Done"
} else {
echo "Request failed: $($R.StatusCode)"
}

REST-API Basic Authentication and Invoke-WebRequest via Powershell

Trying to connect to a REST-API via Powershell client. When testing the endpoint in Postman, I have no problems at all. Here's the main part of the function (I have a [pscredential]$Creds parameter that I use to get the username and password):
[string]$username = $Creds.UserName
[string]$password = (New-Object System.Net.NetworkCredential($Creds.UserName, $Creds.Password, 'Null')).Password
[string]$authorizationInfo= ([Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(('{0}:{1}' -f $username, $password))))
Invoke-WebRequest -Uri "https://$($HostName)/api/" -Method Get -Headers #{Authorization = ('Basic {0}' -f $authorizationInfo)}
For some reason the Authorization header is different in my script than in Postman. I can even copy the Authorization header out of Postman and paste it into the -Headers parameter and everything works fine. I just don't see where I'm getting this wrong.
I can't tell you why that's not working, but I can suggest something that works for me all the time with APIs:
$auth = $username + ':' + $upassword
$Encoded = [System.Text.Encoding]::UTF8.GetBytes($auth)
$authorizationInfo = [System.Convert]::ToBase64String($Encoded)
$headers = #{"Authorization"="Basic $($authorizationInfo)"}
Invoke-WebRequest -Uri "https://$($HostName)/api/" -Method GET -Headers $headers
If that doesn't work, try this subtle difference with Invoke-Restmethod:
Invoke-RestMethod -Uri "https://$($HostName)/api/" -Method GET -Headers $headers
Working with APIs is always an adventure. Keep trying. :)

Invoke-RestMethod : Could not find authentication data on request when send to headers

I added powershell script in azure devops release and try to send POST request using Invoke-WebRequest with Authorization token and xml file.
What am I doing wrong?
I get Authorization token from another POST request and tried to create headers with this token and trying send xml file using x-ray endpoint (NUnit XML results - POST /api/v1/import/execution/nunit)
https://confluence.xpand-it.com/display/XRAYCLOUD/Import+Execution+Results+-+REST#ImportExecutionResults-REST-NUnitXMLresults
Authorization token like headers parameters
Content-type like powershell parameters
$bodyForAuth=#{"client_id"="...";
"client_secret"="...";
}
$jsonAuth=Invoke-WebRequest -Uri $urlForAuth -Method POST -Body ($bodyForAuth|ConvertTo-Json) -ContentType "application/json"
$authToken=ConvertFrom-Json -InputObject $jsonAuth
$headers=#{ Authorization = "Bearer $authToken" }
Invoke-WebRequest -Headers $headers -Uri $urlForXrayApi -Method POST -ContentType "text/xml" -InFile $TestResultsXmlPath
And I have error: "Invoke-RestMethod : Could not find authentication data on request"
Also I try to send like this:
$headers=#{ Authorization = "Bearer $authToken";"Content-Type"="text/xml" }
Invoke-WebRequest -Headers $headers -Uri $urlForXrayApi -Method POST -InFile $TestResultsXmlPath
And also have the same error : "Invoke-RestMethod : Could not find authentication data on request"
But if I send POST request like this (without Content-Type):
$bodyForAuth=#{"client_id"="...";
"client_secret"="...";
}
$jsonAuth=Invoke-WebRequest -Uri $urlForAuth -Method POST -Body ($bodyForAuth|ConvertTo-Json) -ContentType "application/json"
$authToken=ConvertFrom-Json -InputObject $jsonAuth
$headers=#{ Authorization = "Bearer $authToken" }
Invoke-WebRequest -Headers $headers -Uri $urlForXrayApi -Method POST -InFile $TestResultsXmlPath
I have SERVER ERROR: "Invoke-RestMethod : {"error":"Missing data in the nunit results import request"}"
Power Shell v. 5.1
Why when I send to headers server can not fine authorization data?
I needed parenthesis, so I changed $TestResultsXmlPath to $(TestResultsXmlPath)
Invoke-WebRequest `
-Headers $headers `
-Uri $urlForXrayApi `
-Method POST `
-InFile $(TestResultsXmlPath)

Invoke-RestMethod with spaces in vm name

I have a VM called "myannoyingVM1 1"
Invoke-RestMethod -Uri $uri -Method Post -Body "vms,vmid=VirtualMachine-vm-
679,vmname=myannoyingvm1 1 cpu=4,memoryGB=8"
When I try to post this to my influxdb I get the below...
Invoke-RestMethod : {"error":"unable to parse 'vms,vmid=VirtualMachine-vm-679,vmname=myannoyingvm1 1 cpu=4,memoryGB=8':
invalid field format"}
Which makes sense, how do I make it realise that it is one tag
After playing around with escape characters for curl on Windows OS I found \ works.
$b = "vms3,vmid=VirtualMachine-vm-679,vmname=myannoyingvm1\ 1 cpu=4,memoryGB=8"
Invoke-RestMethod -Uri $uri -Method Post -Body $b