Skip to content
Howard van Rooijen By Howard van Rooijen Co-Founder
Create a custom TeamCity PowerShell MetaRunner to Notify NewRelic that new deployment has occurred

Last month I wrote a guest blog post for JetBrains; a detailed step by step guide for creating a custom TeamCity MetaRunner to notify NewRelic that a new deployment has occurred based on a case study I wrote earlier in the year called "From Chaos, Through Fear, To Confidence" which details an ALM and DevOps transformation project we carried out for one of our clients:

devops feedback loops

One of the feedback loops we created was missing from the above diagram was notifying NewRelic that a new deployment had occurred:

teamcity notify newrelic

We implemented this feedback loop with a customer TeamCity MetaRunner. The MetaRunner packaged up and used Curl to call NewRelic's deployment API,  but during the development I discovered a problem using Curl; OpenSSL is a prerequisite for all build agents that will run the MetRunner.

The best hour you can spend to refine your own data strategy and leverage the latest capabilities on Azure to accelerate your road map.

I received a tweet from Stuart Preston asking why I used Curl and couldn't just use PowerShell's Invoke-RestMethod instead; the purpose of the step by step guide was really to show you how to create your own tool based MetaRunner as this feature is not talked about in any documentation and packaging up Curl was the simplest useful example I could think of. The OpenSSL dependency only became apparent after I had written the plugin and ran it on the target server, as I already had OpenSSL installed on my Dev Rig.

Azure Weekly is a summary of the week's top Microsoft Azure news from AI to Availability Zones. Keep on top of all the latest Azure developments!

Based on Stuart's feedback I've created a third implementation of the MetaRunner, which just runs an embedded PowerShell script, using Invoke-RestMethod to notify NewRelic:

  $body = "";

  if ([String]::IsNullOrEmpty($apiKey)){
    throw "API Key is required"
  } else {
    $headers += @{"x-api-key"=($apiKey)};

  if ([String]::IsNullOrEmpty($appName)){
    throw "App Name is required"
  } else {
    $body += "deployment[app_name]=$appName";

  if (![String]::IsNullOrEmpty($changeLog)){
    $body += "&deployment[changelog]=$changeLog";

  if (![String]::IsNullOrEmpty($description)){
    $body += "&deployment[description]=$description";

  if (![String]::IsNullOrEmpty($environment)){
    $body += "&deployment[environment]=$environment";

  if (![String]::IsNullOrEmpty($revision)){
    $body += "&deployment[revision]=$revision";

  if (![String]::IsNullOrEmpty($user)){
    $body += "&deployment[user]=$user";

  $result = Invoke-RestMethod -Uri $url -Headers $headers -Body $body
  Write-Host $result
  Write-Error $_

To package up the plugin, download the source from the GitHub Repo and run Build\build-powershellscrptrunner.cmd to build the plugin zip file. Follow the instructions in the step by step guide for deploying the plugin into TeamCity.

Work Smarter, Not Harder.

@HowardvRooijen | @endjin

Howard van Rooijen


Howard van Rooijen

Howard spent 10 years as a technology consultant helping some of the UK's best known organisations work smarter, before founding endjin in 2010. He's a Microsoft ScaleUp Mentor, and a Microsoft MVP for Azure and Developer Technologies, and helps small teams achieve big things using data, AI and Microsoft Azure.