Uploading a text file to discord using webhook - powershell

I looked through and tested a few examples I saw online with no success.
From what I understand it should look something like the code below:
$hookUrl = 'https://discord.com/api/webhooks/XXXXXXXXXXXXXXXXXXXX'
$Body = #{
'username' = $env:username
'content' = "this is a test"
"file=#C:\Users\User\Desktop\test.txt"
}
Invoke-WebRequest -uri $hookUrl -Method POST -Body $Body -Headers #{'Content-Type' = 'application/json'}
ERRORS
Invoke-WebRequest : {"code": 50109, "message": "The request body contains invalid JSON."}
At line:11 char:1
+ Invoke-WebRequest -uri $hookUrl -Method POST -Body $Body -Headers #{' ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
I have seen a few extensively long methods to achieve this in the documentation, however if you see below I will post a one liner that accomplishes what I want using CMD. Is it really this simple in CMD but in powershell it takes 15+ lines?
curl -F "payload_json={\"username\": \"jakoby\", \"content\": \"download me\"}" -F "file=#\"C:\Users\User\Desktop\newUser.txt\"" WEB-HOOK

Update:
The answer below (next section) addresses the original form of your question.
It later emerged that you're looking for the PowerShell equivalent of a curl command line that uses a multipart/form-data submission to submit both JSON and upload a local file.
Example 6 in the Invoke-WebRequest help topic shows you how to do that, but it is more verbose than the curl command.
The simplest solution may therefore be to simply call your curl command from PowerShell, but be sure to use curl.exe to unambiguously target the external executable, not the curl alias for Invoke-WebRequest that is built into Windows PowerShell (it has been removed in PowerShell (Core) 7+).
curl.exe -F "payload_json={\`"username\`": \`"jakoby\`", \`"content\`": \`"download me\`"}" -F "file=#\`"C:\Users\User\Desktop\newUser.txt\`"" WEB-HOOK
Note the unfortunate need to escape the embedded " twice:
Once, with `, to satisfy PowerShell's syntax requirements for double-quoted strings (as expected).
You could obviate the need for this if you used '...' for the overall quoting, but that would preclude embedding variable values directly in the string.
Unexpectedly again, with \, to work around a long-standing bug with respect to passing arguments containing verbatim " chars. to external programs, still present as of PowerShell 7.2.x - see this answer.
Since the target web service expects JSON, you must convert your $Body hashtable to JSON before passing it to Invoke-WebRequest's -Body parameter, which you can do with ConvertTo-Json:
Invoke-WebRequest -uri $hookUrl -Method POST -Body (ConvertTo-Json $Body) -Headers #{'Content-Type' = 'application/json'}
The obligatory general caveat: with more deeply nested objects, you may need to pass a -Depth argument to ConvertTo-Json to prevent accidental truncation of data - see this post.
It seems that you also want to upload a local file:
Since the web service has no access to your local file system, passing a local file path as part of your JSON cannot work - the local file's content must be uploaded.
The Invoke-WebRequest docs only discuss uploading local files in the context of multipart/form-data submissions - see example 6, for instance.

Related

How to pipe wget results to subsequent curl post?

I am in Windows 10 attempting to get Confluent CE up via docker. See their instructions here.
The trouble is I believe these are specifically for MAC OS, and Windows requires slightly different syntax for the following command:
wget https://github.com/confluentinc/kafka-connect-datagen/raw/master/config/connector_pageviews_cos.config
curl -X POST -H "Content-Type: application/json" --data #connector_pageviews_cos.config http://localhost:8083/connectors
I think I am supposed to be piping the wget results to the curl. How to do that in Windows 10 ?
The powershell exception:
At line:1 char:57
+ ... ntent-Type: application/json" --data #connector_pageviews_cos.config ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~
The splatting operator '#' cannot be used to reference variables in an expression. '#connector_pageviews_cos' can be
used only as an argument to a command. To reference variables in an expression use '$connector_pageviews_cos'.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : SplattingNotPermitted
Thanks!
Both curl and wget are aliased in Powershell 5.1 to Invoke-WebRequest, although it seems that curl.exe is available under System32 (and is available in place of an alias in Powershell Core). But, it's not too difficult to translate both calls to the Powershell-native Invoke-WebRequest cmdlet.
Your wget call becomes:
Invoke-WebRequest -Uri https://github.com/confluentinc/kafka-connect-datagen/raw/master/config/connector_pageviews_cos.config -Outfile connector_pageviews_cos.config
And your curl call becomes:
Invoke-WebRequest -Uri http://localhost:8083/connectors -Method POST -ContentType 'application/json' -Body (Get-Content -Raw connector_pageviews_cos.config)
If desired, you can combine both calls into a single line, as the -Body parameter accepts pipeline input:
Invoke-WebRequest -Uri https://github.com/confluentinc/kafka-connect-datagen/raw/master/config/connector_pageviews_cos.config |
Invoke-WebRequest -Uri http://localhost:8083/connectors -Method POST -ContentType 'application/json'
Omit the -OutFile parameter on the first Invoke-WebRequest, which outputs the payload contents to the pipeline. You then pipe that output into the second Invoke-WebRequest while providing other positional and named arguments as needed.
More information on Invoke-WebRequest is available here, and you would also do well to check out the convenient-to-use Invoke-RestMethod which makes working with RESTful APIs much more comfortable.
As a note, the # operator is used for a concept called splatting in Powershell, which explains the error you were receiving. Read the link above for more information, and elsewhere I've also written an answer on how to use splatting to pass arguments to cmdlets and commands.

How to download a file accepting license using powershell

I am trying to download package from the below link using powershell.
https://www.tenable.com/downloads/nessus-agents
i do not have direct link for these package also when i click on download it ask to agree. I was able to do it on Linux using command shown below. Kindly advise how can i do it in windows.
"wget --no-check-certificate --post-data='accept="I accept the terms of this license"&x=""&sid=5mcia8gchg28attkc9oarah153&p=NessusAgent-7.4.2-amzn.x86_64.rpm' 'https://www.tenable.com/downloads/nessus-agents' -O NessusAgent-7.4.2-amzn.x86_64.rpm"
could not find anything tried option with invoke-webrequest
Invoke-RestMethod -Uri 'https://www.tenable.com/downloads/nessus-agents'
There's a GET query string parameter that indicates acceptance.
Simply add i_agree_to_tenable_license_agreement=true to your query string parameters.
Invoke-WebRequest -Uri 'https://www.tenable.com/downloads/api/v1/public/pages/nessus-agents/downloads/9762/download?i_agree_to_tenable_license_agreement=true' -OutFile 'NessusAgent-7.4.2-x64.msi'
You can easily get the IDs of the other files from their API endpoint like so:
(Invoke-WebRequest -Uri 'https://www.tenable.com/downloads/api/v1/public/pages/nessus-agents' | ConvertFrom-Json).downloads | Format-Table -AutoSize
This is similar syntax in Powershell, but it's just downloading a file with contents "OK".
$body = 'accept="I accept the terms of this license"&x=""&sid=5mcia8gchg28attkc9oarah153&p=NessusAgent-7.4.2-amzn.x86_64.rpm'
$uri = 'https://www.tenable.com/downloads/nessus-agents'
$resp = Invoke-WebRequest -Method Post -Body $body -Uri $uri -OutFile .\NessusAgent-7.4.2-amzn.x86_64.rpm
Maybe the "sid" variable needs to change per request.

why does API call not working in teamcity

I created a powershell script to call rest API. In powershell script I am calling post, get and put methods. script works fine in my machine and also works if I run powershell script directly on build agent machine.
But if I create a build step in team city and call .ps1 (powershell file) POST and GET methods are working but PUT method is not working. Build is failing with error :
"Invoke-RestMethod : {"code":404,"errors":[{}]}"
I used below syntax to call PUT API
Invoke-RestMethod -Uri $memberEditUrl -Method Put -Body $memberEditBody -ContentType "application/json"
I logged this command using Write-Host and after build run I went to build log and clicked on logged API URL and called in browser and it is working.
It's only team city where this is not working.
What could be the issue?
Try not to convert the forward slash "/" and colon ":" which I am replacing with %2F and %3A
Put api in single or double quotes "http://asd.com/abc:1234"
sample example for demo
$person = #{
first='joe'
lastname='doe'
}
$json = $person | ConvertTo-Json
$response = Invoke-RestMethod 'http://example.com/api/people/1' -Method Put -Body $json -ContentType 'application/json'
My problem was resolved by replacing slash ("/") with tilda "~" for parameter value. No change for colon ":" and it worked.

Powershell Invoke-Restmethod Can not use generated Authtoken as an variable

i´am trying to access a RESTAPI via Powershell.
Within the login process an Authtoken is generated and is needed for any later command and has to be put into the header. So far nothing special.
Of course i want to put the generated Authtoken into a variable for easier handling. But i´am unable to do so ...
Here is what i´am trying:
Logging in and getting the Authtoken
$payload = #{"login"="username";"password"="password"}
$AuthToken = Invoke-RestMethod -Method Post -ContentType application/json -Body (ConvertTo-Json $payload) -Uri "https://path/to/api/login"
Because the API accepts the authoken only in a special form i have to edit it a little bit
$AuthToken = $AuthToken.Replace("auth_token=",'"auth_token"="')
$AuthToken = $AuthToken.Insert(73,‚"‘)
The Authtoken before
#{auth_token=rShln/Yc2cepDtzbNFntdZue:9c3ce025e5485b14090ca25500f15fa2}
and after my Treatment
#{"auth_token"="St6tecwEseAQegkfhACXUwaj:d7e3e2095ba31073e3fbc043c4563d28"}
If i manually insert the Authtoken into the Restmethod the call looks this:
Invoke-RestMethod -Method Get -ContentType application/json -Headers #{"auth_token"="JsRaTBRlElpq1jLLX5z3TXUy:91d0e1eee1943f6cd6dbaa1d0b9ba9d0"} -Uri "https://path/to/api/something"
As you may gues this works pretty well! If i now try use the Authtoken from my variable my Rest Call looks like this:
Invoke-RestMethod -Method Get -ContentType application/json -Headers $Authtoken -Uri "https://path/to/api/something"
Powershell gives me the following error
Invoke-RestMethod : Cannot bind parameter 'Headers'. Cannot convert the "#{"auth_token"="St6tecwEseAQegkfhACXUwaj:d7e3e2095ba31073e3fbc043c4563d28"}" value of type "System.String" to type
"System.Collections.IDictionary".
At C:\Users\User\Desktop\xxx.ps1:6 char:70
+ ... -Method Get -ContentType application/json -Headers $AuthToken -Uri "h ...
+ ~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Invoke-RestMethod], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
I have no clue why i´am getting this error and would be so thankfull i someone could help me out on this!
I had this issue when using airtable api.
what i did was just curl "https://api.airtable.com/v0/app----/Post?maxRecords=3&view=Grid%20view" -H #{"Authorization" = "Bearer Your-Api-here"}
And it worked
Iam a newbie here, i just post this here thinking it might help someone, it took me hours to discover this.
So right now it looks like $AuthToken is a string. The string is formatted like you would expect a Hashtable to be, but I don't think it's actually a hashtable. What you can do to fix this is to use Invoke-Expression on the string, and that will convert it to an actual hashtable for you. Something like:
$AuthToken = Invoke-Expression $AuthToken
Invoke-RestMethod -Method Get -ContentType application/json -Headers $Authtoken -Uri "https://path/to/api/something"
The Header should be in System.Collections.IDictionary method (check : https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.system-collections-idictionary-add?view=netframework-4.8)
Example: Am doing it on a centreon api
The header Variable should be: $headers = #{"centreon-auth-token" = "$Key"}
The key contain only the token, example: NWU5ZDY5ODFiNWI2YTYuMzAzNjM3NDI=
Looks like this is an insane PowerShell bug. If you have a tab after -Header $Headers, the casting to Collections.IDictionary fails because the tab is removed somewhere inside.
I'll raise an issue on Github.
Solution is to make sure that there are no tabs between your parameters. They may look the same
Issue raised in PWSH github:
https://github.com/PowerShell/PowerShell/issues/15943
Had a similar issue while trying to run through a tutorial for building APIs with Python (Auth0).
Was able to create a work around by putting the commands into a .sh file, and ran that. Worked running the file.
#James Lear appears the bug is still there

How do I upload an attachment to a JIRA issue via powershell?

I have been searching online for a while and I've not found a solid answer to this (lots of partial answers, though). Still nothing I do works.
I'm trying to write a powershell script to send attachments to JIRA using cURL (have not found another way that I can get to work).
My cURL command is:
C:\opt\curl\curl.exe -u user:pa$$word -X POST -H "X-Atlassian-Token: nocheck" -F "file=#C:\opt\attachments\75391_testingPNG.png" http://jira.ourURL.com/rest/api/2/issue/75391/attachments
This works perfectly from the command line. Anytime I try to run it via powershell it bombs out. Seems like it should be very easy to do, though. Just want to grab the files from a directory and send them to JIRA.
Anyone have any thoughts about this??? Thanks!
I suspect that the characters $ and # in the arguments could be causing you problems (In case that is what you are using). Try escaping them using the backtick symbol.
To start curl.exe using the specified parameters, try the following command:
Start-Process C:\opt\curl\curl.exe -argumentList "-u", "user:pa`$`$Word", "-X", "POST", "-H", "`"X-Atlassian-Token: nocheck`"", "-F", "`"file=`#C:\opt\attachments\75391_testingPNG.png`"", "http://jira.ourURL.com/rest/api/2/issue/75391/attachments"
Basically it means that where you would separate arguments with a space in a command prompt, you would send each argument as an element in a powershell string Array and use it as the value in the -argumentlist parameter to Start-Process.
If you're using PowerShell 3+, you can use the native method Invoke-RestMethod to talk to JIRA, and not have to worry about escaping characters to shell out to a command:
# Build a basic auth header:
$headers = #{
'Authorization' = "Basic $([System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $UserName, $Password))))"
'X-Atlassian-Token' = 'nocheck'
}
Invoke-RestMethod -Uri "http://jira.ourURL.com/rest/api/2/issue/75391/attachments" -Method Post -InFile "C:\opt\attachments\75391_testingPNG.png" -ContentType "multipart/form-data" -Headers $headers
I'm actually not sure what the nocheck header you're adding does though; I've not needed it when talking to JIRA over REST.