How to send an email with PowerShell using SendGrid API

I really like event-driven notifications that can trigger different webhooks and it’s really fun putting them together like pieces of lego to automate workflows.

The most common and simple notification method is via email, but there are scenarios where environments for security reasons and by design have just access to the internet on port 80/443  and this connection is often mediated via a web proxy.

Not having access to SMTP protocol can be a roadblock but, in this article, we will implement a solution to send an email with PowerShell under these limitations without changing Firewall Rules or NSG.

How can we send an email without SMTP (or IMAP)?

SMTP protocol requires TCP port 25 or 587 (with TLS encryption) as the default port for mail submission if those ports are closed my obvious choice is using a web service that will require an API Key as authentication and authorization via web request on HTTPS (using port 443).

In this example, I used Twilio SendGrid (This is not a sponsored article).  It’s very popular and the free tier for this application is probably enough for most testing applications or scenarios.

Once you’ve signed up and created your profile you can click on Settings, API KEYS (https://app.sendgrid.com/settings/api_keys) and CREATE API KEY.

My Personal TIP:  Remember that API KEYs are free, generate one for each of your apps, so it can be considered as a unique identifier so if it gets compromised it’s possible to identify it and to delete it without causing any interruption for other apps using/sharing the same service or account.

Once created, you’ve got everything you need to start using this script.

Send-MailWithSendGrid

I’ve created a PowerShell function that is a wrapper for Invoke-RestMethod and posts the JSON containing the email message the API Key that SendGrid is expecting to receive.

To use this function you can simply import with dot sourcing

Replace these variables with your test values

And finally, run this one-liner

Take advantage of Splatting

Oliver in one of the comments below has pointed out the use of parameter splatting. Indeed, if you have a long list of parameters to pass to a cmd-let or a function in genera is to pack all your variables into a hast table and pass that object to the function.

There are multiple benefits of splatting,  it will not just make your code more readable, but all parameters will be stored into a single object ( hash table),  that will be easy to manipulate, count or iterate if needed.

If you require a proxy

As I’ve mentioned this function is a wrapper of Invoke-RestMethod so it’s simple to check the documentation and for instance adding the proxy address to the Invoke-RestMethod cmd-let.

Wrap-Up

I still think that email communication can be still used effectively today and the choice of having other valid alternatives, for instance, Teams/Slack , can help us to make the right decision when it is okay to use it or simply avoid abusing it.
When we decide that the email is the right solution even when SMTP protocol is not available we can replace the cmd-let of Send-MailMessage with this Send-EmailWithSendGrid using the SendGrid RESTAPI.
As usual, you can find this script on my GitHub Repository.

2 Replies to “How to send an email with PowerShell using SendGrid API”

  1. Hello Paolo,
    can I suggest the use of splatting to pass the parameters to your function
    i.e.
    $MailParams = @{
    From = “[email protected]
    To = “[email protected]
    APIKEY = “MY_API_KEY”
    Subject = “TEST”
    Body =”SENDGRID 123″
    }
    Send-EmailWithSendGrid @MailParams

    The commandline is shoter, and more readable and easily customizable.

    Regards
    Olivier

    1. Hi Oliver,
      Thanks for your comment, yes splatting can make the line for the cmd-let shorter, as much as I like hash tables and I wanted to make the code even simpler.
      I will edit this post and include your comment, I didn’t think to include splatting in this, but, in general, you’re right and it’s a nice option to have all parameters into a single hash table object if you want for instance iterate or manipulate it.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.