PoshCode Logo PowerShell Code Repository

Atlassian Jira Interface by rfoust 3 years ago
embed code: <script type="text/javascript" src="http://PoshCode.org/embed/751"></script>download | new post

This is a set of Powershell functions to interface with the Atlassian Jira bug/issue tracking software using a WSDL interface.

  1. # jirafunctions.ps1
  2. #
  3. # Note: Some functions are incomplete/untested. Be sure to TEST before placing in production!!
  4. #
  5. # Dot-source this script to connect to jira and initialize the functions.
  6. # Ex: PS C:\scripts\jira> . .\jirafunctions.ps1
  7. # Ex: PS C:\scripts\jira> get-JiraReport
  8. #
  9. # Connects to Jira and initializes several functions that can be
  10. # used to interface with Jira.
  11. #
  12. # Author: Robbie Foust (rfoust@duke.edu)
  13. # Last Modified: December 26, 2008
  14. #
  15. # connect-webservice script written by Lee Holmes (http://www.leeholmes.com/guide)
  16. # and slightly modified by Robbie Foust.
  17. #
  18.  
  19. $global:jiraURL = "https://server.yourdomain.com/jira/rpc/soap/jirasoapservice-v2?wsdl"
  20.  
  21. function global:connect-jira ($wsdlLocation)
  22. {
  23.         ##############################################################################
  24.         ##
  25.         ## Connect-WebService.ps1
  26.         ##
  27.         ## From Windows PowerShell, The Definitive Guide (O'Reilly)
  28.         ## by Lee Holmes (http://www.leeholmes.com/guide)
  29.         ##
  30.         ## Connect to a given web service, and create a type that allows you to
  31.         ## interact with that web service.
  32.         ##
  33.         ## Example:
  34.         ##
  35.         ##     $wsdl = "http://terraserver.microsoft.com/TerraService2.asmx?WSDL"
  36.         ##     $terraServer = Connect-WebService $wsdl
  37.         ##     $place = New-Object Place
  38.         ##     $place.City = "Redmond"
  39.         ##     $place.State = "WA"
  40.         ##     $place.Country = "USA"
  41.         ##     $facts = $terraserver.GetPlaceFacts($place)
  42.         ##     $facts.Center
  43.         ##############################################################################
  44. #       param(
  45. #           [string] $wsdlLocation = $(throw "Please specify a WSDL location"),
  46. #           [string] $namespace,
  47. #           [Switch] $requiresAuthentication)
  48.  
  49.         ## Create the web service cache, if it doesn't already exist
  50.         if(-not (Test-Path Variable:\Lee.Holmes.WebServiceCache))
  51.         {
  52.             ${GLOBAL:Lee.Holmes.WebServiceCache} = @{}
  53.         }
  54.  
  55.         ## Check if there was an instance from a previous connection to
  56.         ## this web service. If so, return that instead.
  57.         $oldInstance = ${GLOBAL:Lee.Holmes.WebServiceCache}[$wsdlLocation]
  58.         if($oldInstance)
  59.         {
  60.             $oldInstance
  61.             return
  62.         }
  63.  
  64.         ## Load the required Web Services DLL
  65.         [void] [Reflection.Assembly]::LoadWithPartialName("System.Web.Services")
  66.  
  67.         ## Download the WSDL for the service, and create a service description from
  68.         ## it.
  69.         $wc = new-object System.Net.WebClient
  70.  
  71.         if($requiresAuthentication)
  72.         {
  73.             $wc.UseDefaultCredentials = $true
  74.         }
  75.  
  76.         $wsdlStream = $wc.OpenRead($wsdlLocation)
  77.  
  78.         ## Ensure that we were able to fetch the WSDL
  79.         if(-not (Test-Path Variable:\wsdlStream))
  80.         {
  81.             return
  82.         }
  83.  
  84.         $serviceDescription =
  85.             [Web.Services.Description.ServiceDescription]::Read($wsdlStream)
  86.         $wsdlStream.Close()
  87.  
  88.         ## Ensure that we were able to read the WSDL into a service description
  89.         if(-not (Test-Path Variable:\serviceDescription))
  90.         {
  91.             return
  92.         }
  93.  
  94.         ## Import the web service into a CodeDom
  95.         $serviceNamespace = New-Object System.CodeDom.CodeNamespace
  96.         if($namespace)
  97.         {
  98.             $serviceNamespace.Name = $namespace
  99.         }
  100.  
  101.         $codeCompileUnit = New-Object System.CodeDom.CodeCompileUnit
  102.         $serviceDescriptionImporter =
  103.             New-Object Web.Services.Description.ServiceDescriptionImporter
  104.         $serviceDescriptionImporter.AddServiceDescription(
  105.             $serviceDescription, $null, $null)
  106.         [void] $codeCompileUnit.Namespaces.Add($serviceNamespace)
  107.         [void] $serviceDescriptionImporter.Import(
  108.             $serviceNamespace, $codeCompileUnit)
  109.  
  110.         ## Generate the code from that CodeDom into a string
  111.         $generatedCode = New-Object Text.StringBuilder
  112.         $stringWriter = New-Object IO.StringWriter $generatedCode
  113.         $provider = New-Object Microsoft.CSharp.CSharpCodeProvider
  114.         $provider.GenerateCodeFromCompileUnit($codeCompileUnit, $stringWriter, $null)
  115.  
  116.         ## Compile the source code.
  117.         $references = @("System.dll", "System.Web.Services.dll", "System.Xml.dll")
  118.         $compilerParameters = New-Object System.CodeDom.Compiler.CompilerParameters
  119.         $compilerParameters.ReferencedAssemblies.AddRange($references)
  120.         $compilerParameters.GenerateInMemory = $true
  121.  
  122.         $compilerResults =
  123.             $provider.CompileAssemblyFromSource($compilerParameters, $generatedCode)
  124.  
  125.         ## Write any errors if generated.        
  126.         if($compilerResults.Errors.Count -gt 0)
  127.         {
  128.             $errorLines = ""
  129.             foreach($error in $compilerResults.Errors)
  130.             {
  131.                 $errorLines += "`n`t" + $error.Line + ":`t" + $error.ErrorText
  132.             }
  133.  
  134.             Write-Error $errorLines
  135.             return
  136.         }
  137.         ## There were no errors.  Create the webservice object and return it.
  138.         else
  139.         {
  140.             ## Get the assembly that we just compiled
  141.             $assembly = $compilerResults.CompiledAssembly
  142.  
  143.             ## Find the type that had the WebServiceBindingAttribute.
  144.             ## There may be other "helper types" in this file, but they will
  145.             ## not have this attribute
  146.             $type = $assembly.GetTypes() |
  147.                 Where-Object { $_.GetCustomAttributes(
  148.                     [System.Web.Services.WebServiceBindingAttribute], $false) }
  149.  
  150.             if(-not $type)
  151.             {
  152.                 Write-Error "Could not generate web service proxy."
  153.                 return
  154.             }
  155.  
  156.             ## Create an instance of the type, store it in the cache,
  157.             ## and return it to the user.
  158.             $instance = $assembly.CreateInstance($type)
  159.  
  160.             ## Many services that support authentication also require it on the
  161.             ## resulting objects
  162.             if($requiresAuthentication)
  163.             {
  164.                 if(@($instance.PsObject.Properties |
  165.                     where { $_.Name -eq "UseDefaultCredentials" }).Count -eq 1)
  166.                 {
  167.                     $instance.UseDefaultCredentials = $true
  168.                 }
  169.             }
  170.            
  171.             ${GLOBAL:Lee.Holmes.WebServiceCache}[$wsdlLocation] = $instance
  172.  
  173.             $instance
  174.         }
  175. }
  176.  
  177.  
  178. function global:get-JiraServerInfo
  179.         {
  180.         $jira.GetServerInfo($jiraAuthID)
  181.         }
  182.  
  183.  
  184. function global:get-JiraIssueType
  185.         {
  186.         $jira.GetIssueTypes($jiraAuthID)
  187.         }
  188.  
  189. function global:get-JiraSubtaskIssueType
  190.         {
  191.         $jira.GetSubtaskIssueTypes($jiraAuthID)
  192.         }
  193.  
  194. function global:get-JiraStatus
  195.         {
  196.         $jira.GetStatuses($jiraAuthID)
  197.         }
  198.  
  199. function global:get-JiraPriority
  200.         {
  201.         $jira.GetPriorities($jiraAuthID)
  202.         }
  203.  
  204. function global:get-JiraResolution
  205.         {
  206.         $jira.GetResolutions($jiraAuthID)
  207.         }
  208.  
  209. function global:get-JiraReport
  210.         {
  211.         $jira.GetSavedFilters($jiraAuthID)
  212.         }
  213.  
  214. function global:get-JiraProject
  215.         {
  216.         $jira.GetProjects($jiraAuthID)
  217.         }
  218.  
  219. function global:get-JiraComment ($issueKey)
  220.         {
  221.         $jira.GetComments($jiraAuthID,$issueKey)
  222.         }
  223.  
  224. function global:new-JiraComment ($issueKey, $comment)
  225.         {
  226.         $jiraComment = new-object RemoteComment
  227.         $jiraComment.body = $comment
  228.  
  229.         $jira.AddComment($jiraAuthID, $issueKey, $jiraComment)
  230.         }
  231.  
  232. function global:export-JiraReport ($reportNumber)
  233.         {
  234.         $jira.GetIssuesFromFilter($jiraAuthID, $reportNumber)
  235.         }
  236.  
  237. # needs work
  238. function global:update-JiraIssue ([string]$issueKey)
  239.         {
  240.        
  241.         $jira.UpdateIssue($jiraAuthID,$issueKey,$placeholder)
  242.         }
  243.  
  244. # needs work
  245. function global:set-JiraIssueStatus ($issueKey,$actionID,$placeholder)
  246.         {
  247.         $jira.ProgressWorkflowAction($jiraAuthID,$issueKey,$actionID,$placeholder)
  248.         }
  249.  
  250. function global:get-JiraIssue ($issueKey)
  251.         {
  252.         $jira.GetIssue($jiraAuthID, $issueKey)
  253.         }
  254.  
  255. function global:new-JiraIssue ($project, $type, $summary, $description)
  256.         {
  257.         $jiraIssue = new-object RemoteIssue
  258.         $jiraIssue.project = $project
  259.         $jiraIssue.type = $type
  260.         $jiraIssue.summary = $summary
  261.         $jiraIssue.description = $description
  262.  
  263.         $newIssue = $jira.CreateIssue($jiraAuthID, $jiraIssue)
  264.        
  265.         $newIssue
  266.         }
  267.  
  268. function global:disconnect-jira
  269.         {
  270.         $jira.logout($jiraAuthID)
  271.         }
  272.  
  273.  
  274. $global:jira = connect-jira $jiraURL
  275.  
  276. if (!$credential)
  277.         {
  278.         $global:credential = get-credential
  279.         }
  280.  
  281. $BSTR = [System.Runtime.InteropServices.marshal]::SecureStringToBSTR($credential.Password)
  282. $global:jiraAuthID = $jira.login($credential.UserName.TrimStart("\"),[System.Runtime.InteropServices.marshal]::PtrToStringAuto($BSTR))
  283. [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($BSTR);

Submit a correction or amendment below (
click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:


Remember me