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 $_ } }
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
#>
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Looking back at this , issue type and priority need to have the comment removed.
The end } on them
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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 must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
With this I'm getting a
WARNING: 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 $body
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 may also note that Priority isn't included, that's because our Incident priorities are default to "High" and cannot be adjusted.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
it would be implemented like this:
[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"
$body = [pscustomobject]@{
fields = @{
project= @{ key = $projectKey}
issuetype = @{ name = $issueType }
summary = $summary
description = $description
}
} | ConvertTo-Json
try {
$basicAuth = "Basic " + [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$($Username):$Password"))
$headers = @{
"Authorization" = $basicAuth
"verify" = "false"
}
$requestUri = "$target/rest/api/3/issue"
$response = Invoke-RestMethod -Uri $requestUri -Method POST -Headers $headers -Body $body -ContentType "application/json"
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 must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Okay, I just resolved the proxy issue (temporarily at least), evidently I need to open JIRA up in a web browser, then the script runs without error 407. I'll eventually need to figure out a permanent fix for that.
I attempted your implementation code, and it's returning the same 400 (Bad Request) error. I'm not sure what I'm doing wrong here. It shouldn't matter that I'm using JIRA cloud, correct? This should still work since it works in my Python script, I would imagine.
UPDATE:
I found a workaround ActiveBatch's bug, where it doesn't execute .py scripts properly, it's not the most graceful workaround, but the script works in Python and doesn't in PowerShell, so I just went with Python instead. However, if anyone else has suggestions for a PowerShell fix, I'm all ears.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.