Azure Automation can automatically send emails through alerts when a runbook fails. Unfortunately, these alert mails cannot be adjusted and it is often necessary to send further information. In this case SendGrid is a good alternative because the mail service sends 50,000 mails per month for free.

The following Azure Automation script (you can download the script on github or from the PowerShell-Gallary) takes the essential information and calls the SendGrid REST services with a post message to initiate the mailing:

param (
    [Parameter(Mandatory=$true)] 
    [String]  $SendGridApiCredentialName,

    [Parameter(Mandatory=$true)] 
    [String] $To,
	
    [Parameter(Mandatory=$true)] 
    [String]  $From,

    [Parameter(Mandatory=$true)] 
    [String]  $Subject,

    [Parameter(Mandatory=$true)] 
    [String]  $Body,
	
	[Parameter(Mandatory=$false)] 
    [String]  $SendGridApiUrl = "https://api.sendgrid.com/v3/mail/send"
)

$Cred = Get-AutomationPSCredential -Name $SendGridApiCredentialName
$userName = $Cred.UserName
$securePassword = $Cred.Password
$ApiCred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $userName, $securePassword
$ApiKey = $ApiCred.GetNetworkCredential().Password

$Config = '{"personalizations": [ { "to": [ { "email": "'+$To+'" } ], "subject": "'+$Subject+'" } ], "from": { "email": "'+$From+'" }, "content": [ { "type": "text/html", "value": "'+$Body+'" } ] }'

$Headers = @{"Authorization" = "Bearer " + $ApiKey}
$Result = Invoke-WebRequest -Uri $SendGridApiUrl -Method Post -ContentType "application/json" -Body $Config -Headers $Headers -UseBasicParsing

The script is simple, but still needed two workarounds.

Workaround 1 – Encrypt SecureString

The SendGrid API key is stored as credentials in the Azure Automation Account. Normally this is converted into plain text from a SecureString by using the ConvertFrom-SecureString function:

$ApiKey = ConvertFrom-SecureString $securePassword -AsPlainText

Unfortunately, the -AsPlainText parameter is only available from PowerShell version 7 and AzureAutomation continues to run in PowerShell version 5.1. Therefore, lines 79 and 80 are the workaround for this missing parameter.

Workaround 2 – Missing Token parameter in Invoke-WebRequest

The method Invoke-WebRequest uses the parameters -Authentication and -Token to use a bearer token for the authentication of the web request. So the following lines would have been better alternatives for lines 84 and 85:

$Token = ConvertTo-SecureString -AsPlainText $ApiKey -Force
$Result = Invoke-WebRequest -Uri $Uri -Method Post -ContentType "application/json" -Body $Config -Authentication Bearer -Token $Token

Unfortunately, the two parameters are only supported in PowerShell version 7. In addition, the renewed encryption of the API key could even be saved because the Azure Credentials provide a SecureString that could also be used directly as a token.