Hi all.
Does anyone ever used powershell scripts for creating JIRA issues? Could you provide an example please?
Finally i did it. Here is my script:
[String] $target = "http://jirahost:2990"; [String] $username = "username" [String] $password = "password" [String] $projectKey = "TP"; [String] $issueType = "Task"; [String] $summary = "summary"; [String] $description = "description" [String] $priority = "2" [String] $body = '{"fields":{"project":{"key":"'+$projectKey+'"},"issuetype":{"name": "'+$issueType+'"},"summary":"'+$summary+'","description":"'+$description+'", "priority":{"id":"'+$priority+'"}}}'; function ConvertTo-Base64($string) { $bytes = [System.Text.Encoding]::UTF8.GetBytes($string); $encoded = [System.Convert]::ToBase64String($bytes); return $encoded; } try { $b64 = ConvertTo-Base64($username + ":" + $password); $auth = "Basic " + $b64; $webRequest = [System.Net.WebRequest]::Create($target+"/jira/rest/api/2/issue/") $webRequest.ContentType = "application/json" $BodyStr = [System.Text.Encoding]::UTF8.GetBytes($body) $webrequest.ContentLength = $BodyStr.Length $webRequest.ServicePoint.Expect100Continue = $false $webRequest.Headers.Add("Authorization", $auth); $webRequest.PreAuthenticate = $true $webRequest.Method = "POST" $requestStream = $webRequest.GetRequestStream() $requestStream.Write($BodyStr, 0, $BodyStr.length) $requestStream.Close() [System.Net.WebResponse] $resp = $webRequest.GetResponse() $rs = $resp.GetResponseStream() [System.IO.StreamReader] $sr = New-Object System.IO.StreamReader -argumentList $rs [string] $results = $sr.ReadToEnd() Write-Output $results } catch [System.Net.WebException]{ if ($_.Exception -ne $null -and $_.Exception.Response -ne $null) { $errorResult = $_.Exception.Response.GetResponseStream() $errorText = (New-Object System.IO.StreamReader($errorResult)).ReadToEnd() Write-Warning "The remote server response: $errorText" Write-Output $_.Exception.Response.StatusCode } else { throw $_ } }
Hey Artem.
I think you should take a look here. As it have some explanation on powershell/jira use.
I tend to use the Atlassian CLI, then it is just calling the jira.bat at the command line, plain and simple. And the CLI is quite useable from powershell, VB, VBS, Bach, etc etc - pure KISS :-)
Main challenge can be that using the CLI is relatively slow....
BR,
Normann
The example is 8 years old and was built using the SOAP interface. If that doesn't matter to you, it will be fine. The code example provided above looks to be a C# implementation ported to PowerShell. Works but is not very PowerShelly...
Fortunately it can be boiled down to a few lines of powershell (3.0+) now...
[string] $target = "http://jirahost:2990" [string] $username = "username" [string] $password = "password" [string] $projectKey = "TP"; [string] $issueType = "Task" [string] $summary = "summary" [string] $description = "description" [string] $priority = "2" [string] $body = "{`"fields`":{`"project`":{`"key`":`"$projectKey`"},`"issuetype`":{`"name`":`"$issueType`"},`"summary`":`"$summary`",`"description`":`"$description`",`"priority`":{`"id`":`"$priority`"}}}" try { $basicAuth = "Basic " + [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$($Username):$Password")) $headers = @{ "Authorization" = $basicAuth "Content-Type"="application/json" } $requestUri = "$target/jira/rest/api/latest/issue" $response = Invoke-RestMethod -Uri $requestUri -Method POST -Headers $headers -Body $body -UseBasicParsing Write-Output "ID: $($response.id)" Write-Output "Key: $($response.key)" Write-Output "Self: $($response.self)" } catch { Write-Warning "Remote Server Response: $($_.Exception.Message)" Write-Output "Status Code: $($_.Exception.Response.StatusCode)" }
You don't have to use headers when authenticating on JIRA.
You can use JSON formatted bodies and save the session authentication to a variable to call later
This code will create a session in JIRA, then create a subtask for an issue. if you don't want it as a subtask, change issue type, and remove issue parent.
$global:Summary = "This is the Summary"$global:URI = "https://localhost:8080"$global:IssueParent = "Parent"$global:ProjectKey = "ProjectKey"$global:description = "This is the Issue Description"$body1 = @{ username = $username password = $password } | ConvertTo-Json -Depth 10 #Try/catches are use so that if there is an error, it doesn't continue #create a session in JIRA in order to stay logged in and make changes try { Invoke-RestMethod -uri "$uri/rest/auth/latest/session" -ContentType "application/json" -Method post -body $body1 -SessionVariable mysession } catch { $fullerror = $_.Exception [void][System.Windows.Forms.MessageBox]::Show("Failed to log in with error:`r$fullerror", 'Error') # Casting the method to [void] suppresses the output. $global:StopIssueCreation = $true } #this is a properly formed powershell JSON string #documentation on conversion can be found at #<http://wahlnetwork.com/2016/02/18/using-powershell-arrays-and-hashtables-with-json-formatting/> $global:IssueCreationBody = @{ fields = @{ project = @{ key = $projectKey } parent = @{ key = $issueParent } summary = $summary description = $description issuetype = @{ id = '5' #this is a sub-task issuetype } assignee = @{ name = $username } priority = @{ id = '5' #no priority } } } | ConvertTo-Json -Depth 100 if ($StopIssueCreation -ne $true) #if the login didn't fail { try { $IssueCreation = Invoke-WebRequest -uri "$uri/rest/api/latest/issue" ` -ContentType "application/json" -Method post -Body $IssueCreationBody -WebSession $mysession | ConvertFrom-Json } catch { $fullerror = $_.Exception [void][System.Windows.Forms.MessageBox]::Show("Failed to create Issue in JIRA with error:`r$fullerror", 'Error') # Casting the method to [void] suppresses the output. $global:StopIssueCreation = $true } }<#Use this if you want to add a description Post-Creation#and change the description above to '' if ($StopIssueCreation -ne $true) {$global:descriptionBody = @{ fields = @{ description = $description } } | ConvertTo-Json -Depth 100 try { Invoke-WebRequest -uri "$uri/rest/api/latest/issue/$issueNumber" -ContentType "application/json" -Method put -websession $mysession -Body $descriptionBody | ConvertFrom-Json$global:StopIssueCreation = $true} catch { $fullerror = $_.Exception [void][System.Windows.Forms.MessageBox]::Show("Failed to add Description with error:`r$fullerror", 'Error') # Casting the method to [void] suppresses the output. $global:StopIssueCreation = $true } } #> if ($StopIssueCreation -ne $true) { $global:repairCompleted = $true $global:StopIssueCreation = $false } if ($repairCompleted -ne $true) {} #If the repair didn't complete correctly, maybe tell them something
This one is a little better looking:
$global:Summary = "This is the Summary"$global:URI = "https://localhost:8080"$global:IssueParent = "Project Parent"$global:ProjectKey = "ProjectKey"$global:description = "This is the Issue Description"$body1 = @{ username = $username password = $password } | ConvertTo-Json -Depth 10 #create a session in JIRA in order to stay logged in and make changes Invoke-RestMethod -uri "$uri/rest/auth/latest/session" -ContentType "application/json" -Method post -body $body1 -SessionVariable mysession #this is a properly formed powershell JSON string #documentation on conversion can be found at #<http://wahlnetwork.com/2016/02/18/using-powershell-arrays-and-hashtables-with-json-formatting/> $global:IssueCreationBody = @{ fields = @{ project = @{ key = $projectKey } parent = @{ key = $issueParent } summary = $summary description = $description issuetype = @{ id = '5' #this is a sub-task issuetype } assignee = @{ name = $username } priority = @{ id = '5' #no priority } } } | ConvertTo-Json -Depth 100 $IssueCreation = Invoke-WebRequest -uri "$uri/rest/api/latest/issue" ` -ContentType "application/json" -Method post -Body $IssueCreationBody -WebSession $mysession | ConvertFrom-Json $issueNumber = $IssueCreation.id<##Use this if you want to add a description Post-Creation#and change the description above to ''$global:descriptionBody = @{ fields = @{ description = $description } } | ConvertTo-Json -Depth 100 Invoke-WebRequest -uri "$uri/rest/api/latest/issue/$issueNumber" -ContentType "application/json" -Method put -websession $mysession -Body $descriptionBody | ConvertFrom-Json#>
Invoke-WebRequest : The remote server returned an error: (400) Bad Request.At line:1 char:23+ ... eCreation = Invoke-WebRequest -uri "$uri/rest/api/latest/issue" -Cont ...+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
-----
Please provide your suggestions.
Looking back at this , issue type and priority need to have the comment removed.
The end } on them
With this I'm getting aWARNING: Remote Server Response: The remote server returned an error: (400) Bad Request.Status Code: BadRequest
I know that -UseBasicParsing is no longer a thing (per M$ anyway), so that's been taken out, and I know it's authenticating properly. I feel like this should work, but just isn't for me. I think that the $body variable must have some kind of syntax issue, or maybe because we're on JIRA cloud, it behaves a little differently?I was able to get this working in Python really easily, but I'm trying to make something a little more self-contained for ActiveBatch.This is what I'm working with at the moment
[string] $target = "https://DOMAIN.atlassian.net"[string] $username = 'USERNAME'[string] $password = 'API-KEY'[string] $projectKey = "PROJECT ID"[string] $issueType = "Incident"[string] $summary = "Testing This"[string] $description = "Testing that"[string] $body = "{`"fields`":{`"project`":{`"key`":`"$projectKey`"},`"issuetype`":{`"name`":`"$issueType`"},`"summary`":`"$summary`",`"description`":`"$description`"}}";try {$basicAuth = "Basic " + [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$($Username):$Password"))$headers = @{"Authorization" = $basicAuth"Content-Type" = "application/json""verify" = "false"}$requestUri = "$target/rest/api/3/issue"$response = Invoke-RestMethod -Uri $requestUri -Method POST -Headers $headers -Body $bodyWrite-Output "ID: $($response.id)"Write-Output "Key: $($response.key)"Write-Output "Self: $($response.self)" }catch {Write-Warning "Remote Server Response: $($_.Exception.Message)"Write-Output "Status Code: $($_.Exception.Response.StatusCode)"}
You may also note that Priority isn't included, that's because our Incident priorities are default to "High" and cannot be adjusted.
Try using [pscustomobject]@{} to create your body, then use | convertto-json on it to get the JSON string.
You write it the same way you would a hashtable, but it can have more depth to it
[pscustomobject]@{
Fields = [pscustomobject]@{
Project = @{ key = $projectkey}
IssueType = @{name = $issuetype}
}
} | convertto-json -depth 5
(For simplicity, pscustomobject creates the object as an ordered list, and will not change its order like a hashtable can)
I can't even begin to experiment with this this morning yet, for some reason it's giving me 407 proxy errors now, where when I left friday, it was just the error indicated above.I was curious, however, could you include your solution in the rest of the code? Or an example on where I'd be calling it? I've mostly performed more complex operations in Batch or Python script and I'm not completely familiar with PowerShell yet. I imagine that what you're advising would replace the top section of the script, and then this line
[string] $body = "{`"fields`":{`"project`":{`"key`":`"$projectKey`"},`"issuetype`":{`"name`":`"$issueType`"},`"summary`":`"$summary`",`"description`":`"$description`"}}";
would be calling from the pscustomobject. But I wanted to be sure I had syntax correct for referring to the pscustomobject.
It looks like you're new here. Sign in or register to get started.