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.
Pingback:ICYMI: PowerShell Week of 31-July-2020 | PowerShell.org
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?
Figured out.
Created a new API Key, stored it in Azure and works fine now.
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.
Hi Balaji,
Thank you! At this point, the module is not able to handle multiple recipients yet. But if you can create an issue in the GitHub repository (https://github.com/Ba4bes/PSSendGrid/issues), I can see if I can implement it!
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!
Hi Patrick,
Both a string and an array should work. What is the error message you get?
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!
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.
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
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?
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.
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.
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?
Is it possible to attach multiple attachments or a combination of regular and inline attachments?
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.
Is it possible to add Unsubscribe group id(asm_group_id)?
Could you please describe the functionality you are looking for in an issue at the GitHub repository? <https://github.com/Ba4bes/PSSendGrid>
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
Is your API key correct? If it is, please create an issue with the original code at https://github.com/Ba4bes/PSSendGrid so we can look into it there!
Is it possible to add hyperkink in the body?
Used Hyperlink but not getting the hyperlink instead the whole thing is printed.
Hi Rahul, Could you add this as an issue to the GitHub repo? https://github.com/Ba4bes/PSSendGrid/issues