How to send a slack webhook message for an Azure DevOps pipeline task

I wanted to send a slack message when a deployment completed on Azure. It’s fairly straightforward but there are a couple of things I had to pull together from documentation on slack, PowerShell and azure.

Here is the script I finished with.

Just scroll to the bottom to skip ahead and see the entire script.

You will have to create a webhook url on your slack organisation. I will assume you have done that.

PowerShell task in Azure

You need to select the PowerShell function task in Azure pipelines and change the type to “inline”. You could also ship the script with your code as a ps1 file and just reference it in here. That’s probably a better solution once you have tested inline that it all works for you.

Script outline

In the script I create a function and then immediately call it. The function takes the message text and the web hook url.

I send three parameters to slack.

  1. You should change the username to whatever you like. “My Deploy bot” or something similar.
  2. The text is passed in later and will be replaced.
  3. The emoji appears next to the message. Rolled up newspaper is pretty safe! :)

The text parameter

To reference a user in slack through the webhook you don’t use @channel you must use <!channel>

In this example I add a manually created link to the build. You will have to change the url to your own organisation and project for those to work.

<$($env:RELEASE_RELEASEWEBURL)|$($env:RELEASE_RELEASENAME)> is another useful link to post on slack to take users directly to the relevant release.

In PowerShell you use the format $($env:BUILD_BUILDID) to access the predefined build variables. Notice that different to yaml, we get them through the $env and the . are replaced with _ for PowerShell.

 function Send-SlackMessage {
    param (
        [Parameter(Mandatory=$true, Position=0)]$Text,
        [Parameter(Mandatory=$true, Position=1)]$Url
    $body= @"
        "username": "Loading Bay",
        "text": "MESSAGE_TEXT",

    Invoke-WebRequest -Method Post -Uri $Url -Body $body.Replace("MESSAGE_TEXT","$Text") -ContentType 'application/json'
Write-Host "Sending slack message for BUILD: $($env:BUILD_BUILDID)"

Send-SlackMessage "<!channel> <$($env:BUILD_BUILDID)|Build: $($env:BUILD_BUILDID)> is now on STAGING" ""
Darragh ORiordan

Hi! I'm Darragh ORiordan.

I live and work in Sydney, Australia building and supporting happy teams that create high quality software for the web.

I also make tools for busy developers! Do you have a new M1 Mac to setup? Have you ever spent a week getting your dev environment just right?

My Universal DevShell tooling will save you 30+ hours of configuring your Windows or Mac dev environment with all the best, modern shell and dev tools.

Get DevShell here: ✨

Read more articles like this one...

List of article summaries


Extract user profile attributes from an Azure ADB2C tenant using the Microsoft Graph API

I had to retrieve a list of users from an Azure Active Directory B2C instance today. I thought I could just go through the Azure UI but that’s limited to short pages of data and limited attributes.

There is a CSV export provided on the UI but you won’t get the required identity objects in the csv output if you need a user’s signin email address.

I had to use the Microsoft Graph Api to get what I needed. This is a bit hacky but it does the trick!


Force restart your Azure App service site and host

Sometimes your Azure App service host will need to be restarted. You can do this but it’s hidden away in the Azure resource manager site. Here’s how to find it!


Scheduling a feature toggle using no-code with Azure Logic Apps

I use launch darkly to toggle features on an app. There is one third-party dependency that has regular scheduled maintenance and I need to toggle the feature on and off on schedule.

Launch Darkly has built in scheduling to handle this scenario but you have to be on the enterprise plan to use it. The enterprise plan is too expensive to upgrade to for scheduling alone so I needed to find a different way to automate this.


Avoid rebuild of React App in every CI stage

If you have a react app you can use env vars like REACT_APP_MY_ENV_VAR in your application and React will automatically pull them in to your app when you build the production application.

This is very useful but if you have variables that change for each environment and your application build takes a long time, you might want to avoid building unnecessarily in CI. For example you might have a QA environment and a Staging environment that have different configuration.

We type-check our code on each build and that was taking 5 minutes+ to build each environment so we had to make it faster. We changed our app from using REACT_APP env vars to using a configuration file that we could quickly write to using CI.

Our CI system is Azure DevOops so the CI scripts here are specifically for Azure DevOps but they apply to most CI systems with small changes.

The real work happens in a Node.js script that would work anywhere.