How do I upload an attachment to a JIRA issue via powershell? - 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.

Related

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.

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.

Need curl command to ElasticSearch for PowerShell

My application is spamming my log with disk threshold messages. I already found out (here low disk watermark [??%] exceeded on) what I need to do. I have attached the a curl command below, which should solve my problem. Unfortunately I am in Windows, so no curl.
I have already tried building my own "Invoke-RestMethod" command, which all did not work (and I also forgot to preserve them for reference here). I looked at parse-curl on github, but did not understand how it'll help me. SO I'm a bit lost in documentation... The errors form Invoke-RestMethod in the shell also were not very helpful in the end.
curl -X PUT "localhost:9200/_cluster/settings" -H 'Content-Type: application/json' -d'
{
"persistent" : {
"cluster.routing.allocation.disk.threshold_enabled" : "false"
}
}
'
So... I just need a working command for PowerShell to be happy.
$body = #{
persistent = #{
"cluster.routing.allocation.disk.threshold_enabled" = $false
}
} | ConvertTo-Json
Invoke-WebRequest -Uri "http://localhost:9200/_cluster/settings" -Method Put -Body $body -ContentType "application/json"
Try the above code. Maybe remove the "http://"-part but I don't think so.
Hope this helps!

REST API: adapt a cURL POST to Powershell 5 (upload files)

I have this cURL command that I must adapt to Powershell in order to upload different files. In order to do that, I have mandatory fields that I need use in the request.
I've tried like a dozen of different scripts, nothing works.
Can someone help me out with this?
It should be plain simple, but I am missing something.
cURL command:
curl -H "Authorization: Bearer xxx"
-F "parentDirectoryId=1"
-F "name=AutoUpload"
-F "contents=#C:\temp\test.pdf"
https://url/v1/api/files?
This is going to depend on which version of Powershell you are using. If you have Powershell 6 you can use the simple method below which uses the form parameter. If you use another version you can use the more complicated example #4 which is outlined on the Microsoft Docs:
$Uri = 'https://url/v1/api/files?'
$Form = #{
parentDirectoryId= '1'
name = 'AutoUpload'
contents= Get-Item -Path 'C:\temp\test.pdf'
}
$token = ConvertTo-SecureString "xxx" -AsPlainText -Force
$Result = Invoke-RestMethod -Uri $Uri -Method Post -Form $Form -Authentication Bearer -Token $token
This example uses the new Authentication and Form parameters in Invoke-RestMethod. Depending on your Authentication type, you will need either a Token or Credentials parameter with additional information. The Form parameter simplifies what was previously a complicated process for adjusting the body or URI per request.

What is the curl equivalent command in powershell for uploading the apk file?

I am trying to perform CI/CD using Perfecto and hence I am trying to upload a file to perfecto when my Bamboo build is finished.
I was trying with the following cURL command when we have a Linux server.
curl -X POST --upload-file test.apk 'https://****.perfectomobile.com/services/repositories/media/PRIVATE:test.apk?operation=upload&user=<email>&password=<password>&overwrite=true'
Now our server is changed to Windows and hence I want a powershell script which I can use as an Inline Scripts in Bamboo.
Can you please tell me what is an equivalent script in Powershell for windows.
Many thanks in advance.
# Gather your information.
$email = "myEmail#website.com";
$password = "powershellR0cks!";
$subDomain = "****";
$url = "https://$subDomain.perfectomobile.com/services/repositories/media/PRIVATE:test.apk?operation=upload&user=$email&password=$password&overwrite=true";
$filePath = ".\test.apk";
# Make the request.
$response = Invoke-WebRequest -Uri $URL -Method Post -InFile $filePath -ContentType "application/octet-stream";
# Check for success.
if (-not ($response.StatusCode -eq 200)) {
throw "There was an error uploading the APK manifest.";
}
You may want to check the value of -ContentType, but I think that's correct. You don't necessarily need to include the scheme (HTTPS) if you don't want to, and semicolons in PowerShell are optional, but you can include them if you want.
The $response variable is an HtmlWebResponseObject that has the content of the response, the status code, and a bunch of other useful info. You can check out the available properties and methods on the object by running $response | Get-Member.
Finally, the Invoke-WebRequest cmdlet also has other parameters that may be useful to you, such as -Credential, -Headers, and more.
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=powershell-5.1
As a side-note, if you run Get-Alias -Name "curl", you can see that anytime you use curl in PowerShell, you're really just calling Invoke-WebRequest. You can use the curl alias if you want, but it's generally not a good idea to use aliases in automation since they can be modified or deleted.