How to pipe wget results to subsequent curl post? - powershell

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.

Related

Translate cURL -F (--form) statement to PowerShell

I have a working cURL statement that takes the contents of a .csv file and posts them to a REST endpoint:
curl \
'https://app.sleuth.io/api/1/deployments/<ORG_SLUG>/<DEPLOYMENT_SLUG>/import_deploys' \
-H 'Authorization: apikey <APIKEY>' \
-F 'csv_file=#<FILENAME>.csv'
I am trying to convert it to PowerShell format, but can't seem to get there.
I am fairly new to APIs, so I've been using the Curl2PS tool for translating cURL commands to PowerShell, and it worked fairly well with other types, but it struggles with the -F (--form) parameter. This is what I get when I input the above cURL statement:
WARNING: The parameter '-F' is not yet supported. Please refer to curl man pages: https://curl.se/docs/manpage.html
Invoke-RestMethod -Method Get -Uri 'https://app.sleuth.io/api/1/deployments/<ORG_SLUG>/<DEPLOYMENT_SLUG>/import_deploys' -Verbose:$false -Headers #{
'Authorization' = 'apikey <APIKEY>'
}
It basically only does a partial job at converting the statement and skips the -F part completely, leaving it blank.
After some googling I tried using the -Infile method, but I probably did it wrong (again, noob here):
Invoke-RestMethod -Method POST -Uri 'https://app.sleuth.io/api/1/deployments/<ORG_SLUG>/<DEPLOYMENT_SLUG>/import_deploys'-Verbose -Headers #{
'Authorization' = 'apikey <APIKEY>'
'Content-Type' = 'multipart/form-data'
} -Infile '<FILENAME>.csv'
Unfortunately, I get a Bad Request (400) error.
I tried googling for a solution, but couldn't really find one, so any input here would be much appreciated.

Uploading a text file to discord using webhook

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.

Invoke-WebRequest : Cannot bind parameter 'Headers'

I am trying to execute a curl command in powershell:
curl --user bitcoinipvision --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "move", "params": ["acc-1", "acc-2", 6, 5, "happy birthday!"] }' -H 'content-type: application/json;' http://localhost:18332/
But I get this error, what is the problem?
Invoke-WebRequest : Cannot bind parameter 'Headers'. Cannot convert the
"content-type: application/json;" value of type "System.String" to type
"System.Collections.IDictionary".
At line:1 char:158
+ ... 5, "happy birthday!"] }' -H 'content-type: application/json;' http:// ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Invoke-WebRequest], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
As already stated out by some commenters you will see that curl is actually just an alias to Invoke-WebRequest:
PS> Get-Command curl
CommandType Name Version Source
----------- ---- ------- ------
Alias curl -> Invoke-WebRequest
Note: I suggest to use Get-Command, not Get-Alias because you maybe don't know if the command you are using is an alias, cmdlet, or an executable.
From this point there are two possible ways to solve your issue:
Use PowerShell's Invoke-RestMethod (or, if you are using PowerShell < 3, Invoke-WebRequest):
Invoke-RestMethod -Uri http://localhost:18332/ -Credential bitcoinipvision -body $thisCanBeAPowerShellObject
As you can see, no content-type is needed as JSON is IRM's default content Type; though you can change it using -ContentType.
If available in your current environment, use the original cUrl. You have to type it this way:
curl.exe --user bitcoinipvision --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "move", "params": ["acc-1", "acc-2", 6, 5, "happy birthday!"] }' -H 'content-type: application/json;' http://localhost:18332/
I would definitely prefer the first one over the 2nd one, as PowerShell natively supports JSON answers, which allows you to easily use them, e.g. by piping it to Where-Object, Format-Table, Select-Object, Measure-Object and so much mure. If you prefer to use cUrl, you have to parse the String returned by the curl.exe process on your own. This could also be problematic with binary content.
Curl basically uses Invoke-Webrequest in PowerShell.
As you can see in the error, the header basically accepts the form "System.Collections.IDictionary"n and you are passing through a "System.String".
Converting the Header to a dictionary/hashtable would resolve the issue,
curl --user bitcoinipvision --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "move", "params": ["acc-1", "acc-2", 6, 5, "happy birthday!"] }' -H #{ "content-type" = "application/json"} http://localhost:18332/
I had a similar issue, until i found this:
https://github.com/MicrosoftDocs/azure-docs/issues/31851
"The commands are designed to be ran within the specific VM and in a Bash environment. Not in PowerShell. So the error you see would be expected in most cases."

"Translation" of a Powershell parameter in CURL.EXE parameter

I would like to have
Invoke-webrequest -Uri $LoginPageURL -SessionVariable WebSession
"translated" in an appropriate CURL.EXE (not the alias CURL in PowerShell!) command for some reasons not to be discussed here.
However I am not able do so - please help.

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.