Trigger Jenkins Builds Using PowerShell

If you have spent much time as a system administrator, you will probably have at least heard of Jenkins (or some other build tool like it). In this post, I will show readers how to use PowerShell to trigger a build remotely on Jenkins using the powerful Invoke-WebRequest cmdlet.

Triggering remote Jenkins builds can be useful for scenarios that require a script to be run or some other form of automation. However, the more important takeaway is learning how to use Invoke-WebRequest because it is such a good way to script and automate a variety of different tasks, not just Jenkins builds.

Configure Jenkins

The process of setting up Jenkins jobs to be triggered remotely is a fairly simple process. First, you will need to reach into Jenkins and enable remote builds for the desired job. There is an option in the job called “Trigger builds remotely” which is what allows the job to be called from a script.

The authentication token can be any arbitrary string you choose. Also, note the URL below the authentication token in Jenkins, you will need that later as part of the script to call this job.

PowerShell

The full script with crumb examples can be found here for reference.

The first use case is the simplest and will kick off a Jenkins job that takes no parameters. There are some variables that need to get set to make things easier; they are all listed below. Make sure to match up the variables to your own environment.

>$JenkinsURL = "https://jenkins.example.com"
>$JobName = "my-jenkins-job"
>$JobToken = "xxxxx"
>$Auth = "username:token"

The other main part of the script is building the URL out of the variables that have been configured, and then kicking off a request to the Jenkins job. The steps are pretty straightforward for this process and listed below.

>$FullURL = "$JenkinsURL/job/$JobName/build?token=$JobToken"
>Invoke-WebRequest -UseBasicParsing $FullURL -Method POST -Headers $Headers

More complicated examples require a little bit of extra magic. For example, if you have a Jenkins job that takes parameters as part of the build, you will need to tweak the Invoke-WebRequest command. The first thing to take care of is creating a PowerShell variable that can be converted to JSON so that it can be used as part of the POST. This logic would go just above the original Invoke-WebRequest command from above if you are following along. Otherwise, you can refer to the gist for the complete script.

>$JenkinsParams = @{
"parameter" = @(
@{
name = "parameter1"
value = "foo"
},
@{
name = "parameter2"
value = "bar"
},
@{
name = "myrepo"
value = $MyRepo
},
@{
name = "tag"
value = $GitTag
}
)
}

Then we can convert the variable into JSON so that it can be sent to Jenkins.

> $ParamsJSON = ConvertTo-Json -InputObject $JenkinsParams

To send the request, we just add the -Body flag with our parameters.

> Invoke-WebRequest -UseBasicParsing $FullURL -Method POST -Headers $Headers -Body @{ json = $ParamsJSON }

Jenkins Crumbs

There are a few other tricks that are needed to get the Jenkins crumbs working. If you have cross-site request forgery protection enabled (CSRF), you will need to generate a crumb with your Jenkins username/password. This adds a little bit of extra logic to the script but is pretty straightforward. The first step is to convert the username/password combination.

>$Bytes = [System.Text.Encoding]::UTF8.GetBytes($Auth)
>$Base64bytes = [System.Convert]::ToBase64String($Bytes)
>$Headers = @{ "Authorization" = "Basic $Base64bytes"}

The next step is to send a request to Jenkins to create a crumb that we can use when kicking off a job.

>$CrumbIssuer = "$JenkinsURL/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,`":`",//crumb)"
>$Crumb = Invoke-WebRequest -UseBasicParsing $CrumbIssuer -Headers $Header

Before we can use this crumb, we need to manipulate this string’s contents so that it will fit into the headers dictionary we created above.

>$Regex = '^Jenkins-Crumb:([A-Z0-9]*)'
>$Matches = @([regex]::matches($crumb, $regex, 'IgnoreCase'))
>$RegCrumb = $Matches.Groups[1].Value
>$Headers.Add("Jenkins-Crumb", "$RegCrumb")

Once we have the crumb, we can simply add it to the -Header flag as an additional item to Invoke-WebRequest. Once you have the crumbs added, everything else works the same way.

Bonus – Jenkins PowerShell Module

There is a nice PowerShell module out there for interacting with Jenkins and its API if you need to do more than simply kick off a job. I highly recommend trying this module out if you need to do anything beyond the basics, for example getting job statuses, alerting when a build is kicked off or finished or any other advance build related tasks.

If you have a newer version of PowerShell installed, you can use the package management module to download and install this module.

>Install-Module -Name Jenkins

You might have to install a package or two along the way, just follow the instructions from the PowerShell prompt and you should be good.

Once the module has been installed successfully, it should be added to your path and all the right locations so you can start using it.

if (Test-JenkinsJob -Uri 'https://jenkins.example.com' -Credential (Get-Credential) -Name 'test')

To use the module in your scripts, just import the module and you should be able to start using it.

Import-Module -Name Jenkins
if (Test-JenkinsJob `
-Uri 'https://jenkins.contoso.com' `
-Credential (Get-Credential) `
-Name 'test')

If you use Github for authentication, just add those credentials to a variable. The Jenkins module also has support for creating crumbs; use the same authentication variable to pass into the Get-JenkinsCrumb cmdlet to generate one.

$Crumb = Get-JenkinsCrumb `
-Uri 'https://jenkins.example.com' `
-Credential Get-Credential

Using the Invoke-WebRequest PowerShell Cmdlet

It is very useful to know your way around the Invoke-WebRequest PowerShell cmdlet for interacting with web pages and services. You can think of Invoke-WebRequest as a sort of replacement to Curl on WIndows. The two tools are great (in different ways) at helping you, as a programmer, work with web pages and web requests.

In the example above, I showed how easy it is to write some scripts to automate a Jenkins job, but the Invoke-WebRequest cmdlet can really be used anywhere that requires automation. Feel free to modify the script I made or start making your own with the Jenkins PowerShell module. Once you start discovering all of the capabilities of Invoke-WebRequest, you will quickly find that it can be used for a variety of different tasks.

Want More Tech Insight?

Learn more from Josh and other tech-insiders on the future of technology, including storage, security and system administration. Sign up today to get our free guide to IT compliance!

SmartFile is a business file mangement platform that gives you more control, compliance and security.

TO SIGN UP