Calling Jenkins workflows with PowerShell / Web API

 

This script  shows how to use PowerShell to invoke a Jenkins workflow and retrieve the result.

Finding the results is depenent on each request being submitted with a unique request ID that may be filtered for.  It also assumes that a unique API token for the workflow being called is known.

Unfortunately, the best that can be retrieved at the completion of a Jenkins job is the text based log file.  This resides in a known folder on the jenkins server to the workflow can be hacked to replace the log with something a little more workable like JSON output.

$jobparams = @{}
$RequestId = ([string]([guid]::NewGuid())).Replace('-','').trim()
 
 
# Global Details
$UserName        = "admin"
$JenkinsAPIToken = "3998abba419dd62796175bc1c98c3"
$JENKINS_URL     = "http://jenkinsserver:8080"
$JOB_URL         = "http://jenkinsserver:8080/job/myworkflow/"
 
# Workflow Parameters
$jobparams.Add("MachineIP", "SomeString1")
$jobparams.Add("RequestID", $RequestId)
 
# Load Assemblies
[Reflection.Assembly]::LoadFile( `
  'C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Web.dll')`
  | out-null  
 
 
<#
  Retrieve Crumbs (needed for POST Requets)
#>
 
$headers    = $null
$headers    = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization","Basic "+
  [System.Convert]::ToBase64String(
  [System.Text.Encoding]::ASCII.GetBytes("$($UserName):$JenkinsAPIToken")))
 
$url         = "$($JENKINS_URL)/crumbIssuer/api/xml"
[xml]$crumbs = Invoke-WebRequest $url -Method GET  -Headers $headers
 
# set the CSRF token in the headers
#$webclient.Headers.Add($crumbs.defaultCrumbIssuer.crumbRequestField, $crumbs.defaultCrumbIssuer.crumb)
 
$reqparm     = new-object System.Collections.Specialized.NameValueCollection
 
# set the CSRF token in the headers
$headers.Add($crumbs.defaultCrumbIssuer.crumbRequestField, $crumbs.defaultCrumbIssuer.crumb)
$headers.Add("Accept", "application/xml")
 
 
 
<#
  Construct URL for Build Request
#>
 
$url     = "$($JOB_URL)buildWithParameters?"
 
$count   = 0
foreach ($h in $jobparams.GetEnumerator()) {
$h
    $count  = $count + 1
    $url    = $url + "$($h.Name)=$([System.Web.HttpUtility]::UrlEncode($h.Value))"
    if (!($count -eq $jobparams.Count)){
       $url = $url + "&"
    }
}
 
 
 
$result = $null
 
$jobsubmit = Invoke-WebRequest $url -Method POST  -Headers $headers -ContentType "application/json"
 
#hack to get output
$linearray = $null
$linearray = ($jobsubmit.RawContent).Split()
 
foreach ($line in $linearray) {
if ($line -match "http://"){
  write-output "queue address = $($line)"
  $queueaddress = "$($line)api/xml"
}
}
 
 
$output = $null
 
#Search for the job with unique ID
$url  = "$($JOB_URL)api/xml?tree=builds[actions[parameters[name,value]],number]&xpath=//build[action[parameter[name=`"RequestID`"][value=`"$($RequestId)`"]]]/number&wrapper=job_names"
 
 
$jobnumber = $null
$val = $null
Do { $val++
 
          Start-Sleep -s 2
          $output = Invoke-WebRequest $url -Method GET  -Headers $headers
          if (!($output.Content -match "<job_names>")){
             [xml]$jobdetails=$output.Content
             $jobnumber = $jobdetails.job_names.number
           $val = 10
          }
 
        } while($val -ne 10) 
 
 
$url  =  "$($JOB_URL)$($jobnumber)/consoleText"
$output = Invoke-WebRequest $url -Method GET  -Headers $headers
$output.Content