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:PSModulePathin your PowerShell 7 session. Install from PSGallery withInstall-Module MSGraphMail
Run Import-Module 'MSGraphMail' to load the module into your current session.
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 @MSGraphMailConnectionParametersUsing 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 hinges around a single command Get-MSGraphMail at it's most basic this looks like this.
Using the Splatting technique:
$MailParameters = @{
    Mailbox = '[email protected]'
}
Get-MSGraphMail @MailParametersUsing the Traditional technique:
Get-MSGraphMail -Mailbox '[email protected]'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-MSGraphMailorDelete-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 email requires passing parameters to the New-MSGraphMail commandlet like so:
Using the Splatting technique:
$MailParameters = @{
    From = 'You <[email protected]>'
    To = 'Them <[email protected]>', 'Someone <[email protected]>'
    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 @MailParametersUsing the Traditional technique:
New-MSGraphMail -From 'You <[email protected]>' -To 'Them <[email protected]>', 'Someone <[email protected]>' -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 <[email protected]>' -To 'Them <[email protected]>', 'Someone <[email protected]>' -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 email requires one small alteration of the above command - adding:
Pipeline = $Trueif splatting or
-Pipelineif 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-MSGraphMailThe important part here is | Send-MSGraphMail quite literally | or Pipe and then the next command.
Moving an email requires one small alteration of the Get or New command - adding:
Pipeline = $Trueif splatting or
-Pipelineif 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.
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:$FalseDisecting 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