MS Graph Mail - A pure-PowerShell Graph API mail client
Preparations
You will need the following:
- An Azure AD Application ID
- An Azure AD Application Secret
- An Azure AD Tenant ID
- PowerShell 7 installed on your Windows, Linux or MacOS device.
- The code from this module in your PowerShell modules folder find this by running
$env:PSModulePath
in your PowerShell 7 session.
Import the Module
Run Import-Module 'MSGraphMail'
to load the module into your current session.
Connecting to the Microsoft Graph API
Connecting to the Microsoft Graph API uses the Azure AD Application information and the Connect-MSGraphMail client application.
Using the Splatting technique:
Splatting is a system in PowerShell that lets us put our parameters in a nicely formatted easy to read object (a HashTable to be specific!) and then "splat" them at the command. To do this, first things first setup a PowerShell object to hold your credentials. For example:
$MSGraphMailConnectionParameters = @{
ApplicationID = '<YOUR APPLICATION ID>'
ApplicationSecret = '<YOUR APPLICATION SECRET>'
TenantID = '<YOUR TENANT ID>'
}
Connect-MSGraphMail @MSGraphMailConnectionParameters
Using the Traditional technique:
If you don't want to - or can't "splat" - we can fall back on a more traditional route:
Connect-MSGraphMail -ApplicationID '<YOUR APPLICATION ID>' -ApplicationSecret '<YOUR APPLICATION SECRET>' -TenantID '<YOUR TENANT ID>'
Getting Emails
Getting emails hinges around a single command Get-MSGraphMail
at it's most basic this looks like this.
Using the Splatting technique:
$MailParameters = @{
Mailbox = 'you@example.uk'
}
Get-MSGraphMail @MailParameters
Using the Traditional technique:
Get-MSGraphMail -Mailbox 'you@example.uk'
You can get more specific with the following parameters:
- MessageID - Retrieves a single message by ID.
- Folder - Retrieves messages (or a single message) from a specific folder.
- HeadersOnly - Retrieves only the message headers.
- MIME - Retrieves a single message in MIME format (Requires MessageID).
- Search - Searches emails based on a string.
- PageSize - Retrieves only the given number of results.
- Pipeline - Formats the output for Pipelining to other commands - like
Move-MSGraphMail
orDelete-MSGraphMail
. - Select - Retrieves only the specified fields from the Graph API.
- Summary - Displays a summary of the message(s) retrieved. See #1 for details.
Creating an E-Mail
Creating an email requires passing parameters to the New-MSGraphMail
commandlet like so:
Using the Splatting technique:
$MailParameters = @{
From = 'You <you@example.uk>'
To = 'Them <them@example.com>', 'Someone <someone@example.com>'
Subject = 'Your invoice #1234 is ready.'
BodyContent = 'X:\Emails\BodyContent.txt'
FooterContent = 'X:\Emails\FooterContent.txt'
Attachments = 'X:\Files\SendtoExample.docx','X:\Files\SendToExample.zip'
BodyFormat = 'text'
}
New-MSGraphMail @MailParameters
Using the Traditional technique:
New-MSGraphMail -From 'You <you@example.uk>' -To 'Them <them@example.com>', 'Someone <someone@example.com>' -Subject 'Your invoice #1234 is ready.' -BodyContent 'X:\Emails\BodyContent.txt' -FooterContent 'X:\Emails\FooterContent.txt' -Attachments 'X:\Files\SendtoExample.docx','X:\Files\SendToExample.zip' -BodyFormat 'text'
If this works we'll see:
SUCCESS: Created message 'Your invoice #1234 is ready.' with ID AAMkADg0MTI1YTY5LTZhNTAtNGY2Ni1iYmFmLTYyNTIxNmQ3ZTAyMQBGAAAAAADcjV4oGXn1Sb6mQOgHYL6tBwAynr9oS8bwR42_Ec20-qUkAAAAAAEQAAAynr9oS8bwR42_Ec20-qUkAAcuZgfeAAA=
A draft email will have appeared in the account provided to From
. Unless you specify the -Send
parameter which immediately sends the email bypassing the draft creation.
You can use inline attachments by using -InlineAttachments
and specifying attachments in the format 'cid;filepath'
e.g:
New-MSGraphMail -From 'You <you@example.uk>' -To 'Them <them@example.com>', 'Someone <someone@example.com>' -Subject 'Your invoice #1234 is ready.' -BodyContent 'X:\Emails\BodyContent.html' -FooterContent 'X:\Emails\FooterContent.html' -Attachments 'X:\Files\SendtoExample.docx','X:\Files\SendToExample.zip' -BodyFormat 'html' -InlineAttachments 'signaturelogo;X\Common\EmailSignatureLogo.png', 'productlogo;X:\Products\Widgetiser\WidgetiserLogoEmail.png'
The two inline attachments would map to:
<img alt="Our Logo" src="cid:signaturelogo"/>
and
<img alt="Widgetiser Logo" src="cid:productlogo"/>
respectively.
Sending an E-Mail
Sending an email requires one small alteration of the above command - adding:
Pipeline = $True
if splatting or
-Pipeline
if using traditional parameter passing.
This tells the command that we're going to pipeline the output - specifically that we're going to send it to another command. In our case we'd end up doing:
New-MSGraphMail @MailParameters | Send-MSGraphMail
The important part here is | Send-MSGraphMail
quite literally |
or Pipe and then the next command.
Moving an E-Mail
Moving an email requires one small alteration of the Get or New command - adding:
Pipeline = $True
if splatting or
-Pipeline
if using traditional parameter passing.
This tells the command that we're going to pipeline the output - specifically that we're going to send it to another command. In our case we'd end up doing:
New-MSGraphMail @MailParameters | Move-MSGraphMail -Destination 'deleteditems'
The -Destination
parameter for Move-MSGraphMail
accepts a "well known folder name" e.g: "deleteditems" or "drafts" or "inbox" or a Folder ID.
The important part here is | Move-MSGraphMail
quite literally Pipe (|) and then the next command.
Deleting an E-Mail
If you want to "permanently" delete an email you can pipe the email to the Remove-MSGraphMail
command. Similar to moving an email this works as so:
Get-MSGraphMail @MailParameters | Remove-MSGraphMail -Confirm:$False
Disecting this - we're getting the mail and then passing it down the pipeline an telling Remove-MSGraphMail
not to prompt us for permission by setting -Confirm:$False