Send simple email in Azure DevOps using PowerShell (without any smtp server)

Rajeev Gupta
Globant
Published in
4 min readNov 6, 2020

--

Introduction:

This article is the first one in the series related with Azure Devops Automations where without any specific tasks we can achieve many automations using scripts(Mainly Powershell). This article is all about sending simple emails in azure pipeline PowerShell task without any need of smtp server or marketplace task. This solves a lot of security issues where projects are not allowed to use outside SMTP servers. All mails will be sent by Azure DevOps azuredevops@microsoft.com.

Background

We encounter situations where we need to send simple emails to notify quick custom details to Azure DevOps team members. We may use it to send details based on the outcome of some script or task or job. For example, if we are using automation to check what all SPNs are getting expired in the next 10 days. So far we have to use sendgrid or any third-party mail service where we have to set smtp server details to send even a simple mail.

Solution:

We can use this simple send mail code which uses Azure Devops’s unpublished SendMail RestApi to send emails to designated people without setting up any smtp server or third-party tool. All emails will be delivered as coming from Azure DevOps <azuredevops@microsoft.com>

We can only send emails to team members who are present there in Azure DevOps projects. Azure Rest API which sends mail uses only tfsid for sending mails so we need to get all tfsids corresponding to emails of receivers.

Prerequisite:

As Rest Api calls are made in the task so we must enable a checkbox for Allow scripts to access OAuth Token in the Agent Job settings as shown on the screen below.

The script achieves below things:

First Step: Using Rest api calls we get all teams info in devops project then from each team we get details of all members in the project.

Second Step: Now from members info we get their email ids and associated TFSIDs. From the master information we filter the list of TFSids associated with the intended receiver’s emails.

Third Step: Send Mail after forming Mail request object with given subject and custom mail body.

Implementation details of all three steps are in the code below.

Detailed code snippet

################# ##################

## Only following 5 variables are required to send mail$myorg = “my-ado-org”$myproj = “my-ado-project”$sendmailto = “devops.user1@xyz.com,devops.user2@xyz.com” ## comma separated email ids of receivers$mysubject = “my custom subject of the mail” ## Subject of the email$mailbody = “my custom mail body details” ## mail body########################### Get tfsids of users whom to send mail$mailusers = “$sendmailto”$mymailusers = $mailusers -split “,”$pat = “Bearer $env:System_AccessToken”$myurl =”https://dev.azure.com/${myorg}/_apis/projects/${myproj}/teams?api-version=5.1"$data = Invoke-RestMethod -Uri “$myurl” -Headers @{Authorization = $pat}$myteams = $data.value.id##Get list of members in all teams$myusersarray = @()foreach($myteam in $myteams) {$usrurl = “https://dev.azure.com/${myorg}/_apis/projects/${myproj}/teams/"+$myteam+"/members?api-version=5.1"$userdata = Invoke-RestMethod -Uri “$usrurl” -Headers @{Authorization = $pat}$myusers = $userdata.valueforeach($myuser in $myusers) {$myuserid = $myuser.identity.id$myusermail = $myuser.identity.uniqueName$myuserrecord = “$myuserid”+”:”+”$myusermail”$myusersarray += $myuserrecord}}## filter unique users$myfinalusersaray = $myusersarray | sort -Unique## create final hash of emails and tfsids$myusershash = @{}for ($i = 0; $i -lt $myfinalusersaray.count; $i++){$myusershash[$myfinalusersaray[$i].split(“:”)[1]] = $myfinalusersaray[$i].split(“:”)[0]}#### create list of tfsid of mailersforeach($mymail in $mymailusers) {$myto = $myto +’”’+$myusershash[$mymail]+’”,’}##send mail$uri = “https://${myorg}.vsrm.visualstudio.com/${myproj}/_apis/Release/sendmail/$(RELEASE.RELEASEID)?api-version=3.2-preview.1"$requestBody =@”{“senderType”:1,“to”:{“tfsIds”:[$myto]},“body”:”${mailbody}”,“subject”:”${mysubject}”}“@Try {Invoke-RestMethod -Uri $uri -Body $requestBody -Method POST -Headers @{Authorization = $pat} -ContentType “application/json”}Catch {$_.Exception}

How to run

Create a PowerShell task (e.g. sendmail) after regular tasks. Use the above code in this PowerShell task. Update first five variables as mentioned in the code snippet above and per your project and mail list. When the pipeline runs it will execute and send mail to all email ids mentioned in sendmailto variable. Screen shot is given below.

Limitations:

Though we can send simple emails using the above scripting method, it is limited to sending simple emails only as there is no way we can format our mails and they go as simple text mails. Second,we can only send mails to persons who are part of azure devops project as sendmail feature works on mapping email ids with tfsids of projects and outsiders will not have any corresponding tfsid so mail will not go to them. We use unpublished sendmail rest api so it always carries a risk of getting decommissioned or deprecated in future.

Conclusion:

This simple email script works wonders when we want to active quick email notification and when the organisation mailbox is not allowed to accept mails from unauthorised mail boxes and not allowed to use third party smtp servers in DevOps Projects.

--

--