Okay, Microsoft Graph API is cool, but sometimes it’s boring to deal with all these hashtables and arrays.
The Send-MgUserMail is a great graph cmdlet to send Emails using the Graph API endpoint. In a previous post, I explained the details and parameters for the Send-MgUserMail. Read more in Send-MgUserMail BodyParameter Explained.
Going through the required hashtables and arrays is a challenge and its more complicated when you want to send emails to multiple users.
Indeed Send-MailMessage
was simple and easy to use, just type the parameter and set the value, and you are good to go. This is what I want to do but using the Graph API.
The Send-GraphMail script uses Microsoft Graph API to send emails to multiple users and also supports sending an email with a single attachment or multiple attachments.
Table of Contents
Downloading and Update History
You can download the PowerShell script Send-GraphMail from my GitHub Repo or PSGallery using the following line.
Install-Script -Name Send-GraphMail
The latest version, 1.2.4, dated the 8th of October 2022
In version 1.2.4, there is no need to import the function to PowerShell. The function is removed, and you can call the script directly with all the same parameters.
C:\MyScript> .\Send-GraphMail -To 'User1@domain.com' -Subject "Test Message" -MessageFormat HTML -Body "I love PowerShell Center"
GraphDebug
Parameter added so you see and read the processing of the email on the Microsoft Graph side.
Also, this version support using Microsoft personal accounts such as live.com and outlook.com
Send-GraphMail
The Send-GraphMail
sends Microsoft Graph email messaging using a simplified approach that looks similar to Send-MailMessage, but through utilizing the Send-MgUserMail in the background.
This script will build all the required parameters for you and send the email. It’s possible also not to send the email but instead take the JSON request only so you can use it in any other app to send the email.
This decrease the time an admin needs to go through these nested arrays and hashtable.
I love the community work, feel free to send a pull request and update what you wish, add you name and merge it.
Later on I will add additional parameters to the Send-GraphMail
Supported Parameters
Send-GraphMail Support the following parameters:
- [Array] To: The recipient’s address/s can be an array for multiple accounts. Just make sure to include the array type @(“User1@domain.com”,”User2@Domain.com”)
- [Array] Bcc: Similar to To, but this is the BCC and also supports an array of recipients
- [Array] CC: Similar to To and Bcc, it also supports an array of recipients.
- [String] Subject: The Message Subject
- [String] MessageFormat: it can be HTML or Text
- [String] Body: The Message Body you want to send.
- [Switch] BodyFromFile: Using it means the body is stored in a file in your hard drive. When using the BodyFromFile, the Body parameter should be the full path of the file.
- [Switch] DeliveryReport: Set to receive a delivery report email or not
- [Switch] ReadReport: set to receive a read report or not.
- [Switch] Flag: enable the follow-up flag for the message
- [ValidationSet] Importance: Set the message priority. It can be one of the following, Low or High
- [String] Attachments: The Attachment file path. For now, it only supports 1 attachment. If you want more, let me know
- [String] DocumentType: The attachment MIME type, for example for text file, the DocumentType is text/plain
- [Switch] ReturnJSON: This won’t send the email, but instead, it returns the JSON file fully structured and ready, so you can invoke it with any other tool.
- [HashTable] MultiAttachment: Use this parameter to send more than one attachment, this parameter is a Hashtable as the following @{“Attachment Path No.1″=”DocumentType”;”Attachment Path No.2″=”DocumentType”}. You cannot use the
MultiAttachment
withAttachments
parameter - [Switch] GraphDebug: Enable debug log. The debug log is generated by the
Send-MgUserMail
Beta endpoints are not included, such as Mentions.
EXAMPLE
Here are some examples of how to use the script.
Send a Graph email message to multiple users with attachments and multiple To, CC and single Bcc, also request the Delivery and Read reports.
C:\MyScript> .\Send-GraphMail -To @('user1@domain.com','user2@domain.com') -CC @('cc@domain.com','cc1@domain.com') -Bcc "bcc@domain.com" -Subject "Test Message" -MessageFormat HTML -Body 'This is the Message Body' -DeliveryReport -ReadReport -Attachments C:\MyFile.txt -DocumentType 'text/plain'
Send Graph email, load the Body from a file stored locally. Make sure to use the BodyFromFile
switch.
C:\MyScript> .\Send-GraphMail -To 'User1@domain.com' -Subject "Test Message" -MessageFormat HTML -Body C:\11111.csv -BodyFromFile -DeliveryReport -ReadReport -Flag -Importance High -Attachments 'C:\MyFile.txt' -DocumentType 'text/plain'
Send Graph mail with multiple attachments.
C:\MyScript> .\Send-GraphMail -To "ToUser@powershellcenter.com" -Subject "Test V1" -MessageFormat HTML -Body "Test" -MultiAttachment @{"C:\11111.csv"="text/plain";"C:\222222.csv"="text/plain"}
Return and get how the JSON is structured without sending the Email. This is done by using the –ReturnJSON
Parameter
$JSONFile=C:\MyScript> .\Send-GraphMail -To 'vdi1@domain.com' -Subject "Test Message" -MessageFormat HTML -Body "Hi This is New Message" -Flag -ReturnJSON
The output of the above line looks like this
{
"Message": {
"ToRecipients": [
{
"EmailAddress": {
"Address": "vdi1@domain.com"
}
}
],
"Body": {
"Content": "This is the Message Body",
"ContentType": "HTML"
},
"Subject": "MySubject"
}
}
I hope this script helps simplify a common task. Let me know in the comments.
What is the proper way to send multiple attachments, each with their own ContentType?
Hi,
Interesting point. I will update the script to make it support multiple attachment and multiple attachment type.
Hi
I updated the script to support multiple attachments
Here is an example
Send-GraphMail -To "ToUser@powershellcenter.com" -Subject "Test V1" -MessageFormat HTML -Body "Test" -MultiAttachment @{"C:\11111.csv"="text/plain";"C:\222222.csv"="text/plain"}
Make sure to download the latest version 1.1
Thank you Faris Malaeb for this excellent script for your kindness, your fair play, your patience and your skills which are immense 🙂 During the weekend we debugged PowerShell blockages which were not originally planned but, thanks to your support it was a success. Too bad that on the web you can’t find more developers with this talent and intelligence to support even beginners like me. Hats off 🙂 See you soon Faris and take care Richard
This is a decent script, I’ve just spent a few hours trying to accomplish the same thing! I do like the addition of returning the JSON as that could be useful. The only issue I can see is that you can’t send attachments over 3MB using this script. That was a bit of a nightmare to implement due to lack of good documentation from Microsoft!
Mmmmm, interesting. Thanks for the point.
Yes, there is a limitation
There is a fix for this message resource type
I will check this soon and update the script.
Follow this post to get update
I think the only way to fix this is by creating an upload session attached to a mail message, uploading the file(s) in chunks, and then adding them to the message before sending (https://learn.microsoft.com/en-us/graph/outlook-large-attachments). Adding the functionality tripled the size of my script!
Thanks for sharing, I will take a look and try it from my side 🙂
Hi Faris… Been playing around with your script; nice work!
However, I found an error in the script I installed from the powershellgallery
The script doesn’t accept the subject param because you have it hard-coded (see code below)
## Body Subject Parameter
switch ($PSBoundParameters.ContainsKey(‘Subject’)) {
$true { $Body.Message.Add(‘Subject’,”MySubject”) }
$false {}
}
I think you meant to use this instead
## Body Subject Parameter
switch ($PSBoundParameters.ContainsKey(‘Subject’)) {
$true { $Body.Message.Add(‘Subject’,$Subject) }
$false {}
}
Hi Mike, Glad to see your name on my small site 🙂
Thanks for the comment.
I fixed the script issue and replace it with the correct code