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
CodePudding user response:
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
curlcommand line that uses amultipart/form-datasubmission to submit both JSON and upload a local file.Example 5 in the
Invoke-WebRequesthelp topic shows you to do that, but it is much more verbose than thecurlcommand.The simplest solution may therefore be to simply call your
curlcommand from PowerShell, but be sure to usecurl.exeto unambiguously target the external executable, not thecurlalias forInvoke-WebRequestthat 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.
- You could obviate the need for this if you used
- 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.
- Once, with
- Note the unfortunate need to escape the embedded
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-WebRequestdocs only discuss uploading local files in the context ofmultipart/form-datasubmissions - see example 5, for instance.
