Menu Close

PSSendgrid: Send email from PowerShell with Sendgrid

At the start of this year, I created a blog post on sending email from PowerShell through the SendGrid API.
I got a lot of comments on that post from people asking for more options, like sending attachments. So I did some more research and extended the PowerShell function from the previous post.
To make it more accessible, I have uploaded the cmdlet as a module to the PowerShell gallery. With this post, I present you PSSendgrid.

What is SendGrid?

SendGrid is a tool that is often used for marketing emails and newsletters. Along some other services it provides an API and SMTP service that you can use to make sending emails pretty straightforward.

You don’t authenticate against the account you use as the From-address. This means you don’t have to store those credentials. Unfortunately this also means that if you don’t prepare your environment, your email will be marked as unsafe, end up in the spam folder or be rejected (depending on the DMARC settings of the receiving party). And it should, because you are not authorized to use that address.

You do need to create an account with SendGrid, so you are not completely anonymous. But you should have control of the SPF records of the domain you are sending from and use Domain Authentication to make sure your email is not marked as spam.

Prerequisites

To make use of the module, you need to setup a SendGrid account so you can get a token. You can start using Send Grid for free. For example, you can create an account through Azure like this.

I want to mention again that your email will probably end up in the spam folder if you do not prepare the email security settings for your environment (like SPF, DKIM and DMARC). This risk gets bigger when using attachments.
To make sure your email is secure and not considered spam, see the following guides about changing your SPF record and setting up domain authentication.

https://sendgrid.com/docs/glossary/spf/
https://sendgrid.com/docs/ui/account-and-settings/how-to-set-up-domain-authentication/

For other pointers on starting with SendGrid and PowerShell, read my previous post.

PSSendgrid

I have uploaded PSSendgrid to the PowerShell gallery so you can easily access the function.
PSSendGrid has been tested on Windows with Windows PowerShell 5.1 and PowerShell 7. I expect it to also work on Linux and Mac, but have not tested the functionality.

To use it on your computer, first install the module with this cmdlet

Install-Module -Name PSSendGrid

Import the module by using

Import-Module -Name PSSendGrid

You now have the cmdlet Send-PSSendGridMail available to use. I will go through some examples of how to make use of the cmdlet.

Send a basic email

To send a basic email without attachments and HTML, use the following code:

(Notice how Outlook marks the email as not trusted. This is the default behavior)

Send an email with an attachment

You can add an attachment to an email in the following way


Send an email with an inline picture

You are also able to use an attachment as an inline picture for an HTML email. Not every email provider will work with this approach though, so to be sure to test your email.

Send an email to multiple people

Update 29-07-2021: Multiple receivers, in To, CC or BCC, are now supported within the cmdlet!

You can use the following syntax:

You can also still use PowerShell logic to send mail in bulk. For example, to send the same email to multiple email addresses, you could use the following code:

Conclusion

I hope PSSendGrid will help you to send email with PowerShell and SendGrid. It is hard to test every kind of use case, so if you find something that does not work, don’t hesitate to create an issue here.

If you want to view the code, it is all available at my GitHub.

22 Comments

  1. Pingback:ICYMI: PowerShell Week of 31-July-2020 | PowerShell.org

  2. raymond

    Hello,

    It all looks great to me.

    I am a newbee and still get an error

    Line |
    204 | Invoke-RestMethod @Parameters
    | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    | {“errors”:[{“message”:”The provided authorization grant is invalid, expired, or revoked”,”field”:null,”help”:null}]}

    Can you please help what I am doing wrong?

  3. Balaji Shinde

    Great Article, works for me. Can we send one email to multiple recepients rather than sending seperately to each? We want the recepients to be able to see who all are other recepients in the email.

  4. Patrick

    Hi Barbra,

    I’m struggling to figure out how to send an email based on a variable. I am trying to send an email to multiple recipients and am following the examples you’ve provided.

    In the parameters I’ve tried passing assigning the following:

    Attempt 1:
    ToAddress = @($ToAddress)

    Attempt 2:
    ToAddress = $ToAddress

    I’ve tried to pass these as both string and array data types.. At this point I’m not sure how to proceed. Any words of wisdom would be appreciated, thank you!

      • Patrick

        Hi Barbra, I was able to send an email to multiple addresses as parameterized values. My first attempt worked with with the following assignment.

        $ToAddress = “User@email.com”,”User1@email.com”

        Thank you for the response!

  5. veera

    Invoke-RestMethod :
    413 Request Entity Too Large
    413 Request Entity Too Large
    nginx
    At line:72 char:5
    + Invoke-RestMethod @Parameters
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

    I know it is size issue, Im using sendgrid api with powershell to send testreport and the size is about 27mb. Im getting this error. the code works fine for other emails.

    • Barbara

      There is a limitation to the size of the message in SendGrid. Their documentation says it is 30MB for the whole message. So you could try to minimize the message itself. If that doesn’t work it might be better to try to split your report up or store it somewhere and provide a link in your message. More info can be found here

  6. yash

    Hi man,
    Trust you’re doing good.
    I just wanna know how to send an email on a specific date?
    example: suppose I’m getting this date 2022-03-21 as a output.
    is it possible to send an email on specific date which we are getting as an output?

    • Barbara

      Hi Yash,
      at this point this is not possible in the module. But I think it is possible to create this option. Could you create an issue at the GitHub Repository? https://github.com/Ba4bes/PSSendGrid/issues. Then I can keep track of when I find time to research this.

      As a workaround, you could create a scheduled task from your script (an example can be found in this post . Or you could schedule a runbook if you work in Azure, some scripts for that can be found here.

  7. James

    HI,

    I am able to sent mail by using above script. If i schedule it in Task scheduler then it is not working. Could you please help on this.

    • Barbara

      Hi James,
      Can you tell me what goes wrong in the task scheduler? Can you make your script create a log so you can see an error message?

    • Barbara

      You are not able to combine inline and regular, this is a limitation of the REST API.
      You are able to attach multiple attachments, the parameter for that is an array.

  8. Samson

    I am getting the below error , can you please share some insight on the below

    Invoke-RestMethod : Unable to connect to the remote server

    + Invoke-RestMethod @Parameters
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [Invoke-RestMethod], WebException
    + FullyQualifiedErrorId : System.Net.WebException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

Leave a Reply

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