Using Send-MgUserMessage to send Email (with Attachments)

EDIT 25Oct2021:

This article discusses Send-MgUserMessage, though I’ve since realized Send-MgUserMail might be a more efficient option in many cases.

EDIT 27Oct2021:

I have written a follow on-article for Send-MgUserMail. Check it out when you’re done with this one.

Original Post:

I’ve been incorporating the new “SDK” cmdlets into my work lately, and though I’m not entirely convinced using them is any easier than just working with Graph directly, I wanted to update an old script that used Send-Mailmessage, and managing tokens and HTTP headers felt like overkill. Speaking of Send-MailMessage, you may have noticed this harshly worded message on its help page:


The Send-MailMessage cmdlet is obsolete. This cmdlet does not guarantee secure connections to SMTP servers. While there is no immediate replacement available in PowerShell, we recommend you do not use Send-MailMessage. For more information, see Platform Compatibility note DE0005.

Send-MgUserMessage is arguably the most direct replacement (see 25Oct2021 edit), but it is more difficult to use, due to the fact we need to build several custom objects, whereas with Send-MailMessage, the parameters did the work for us.

In my scenario, I also wanted this task to run as an application, defined in Azure Active Directory, using application permissions – not delegated through my personal account. Additionally, I wanted to use a certificate to authenticate to Azure instead of managing a “client secret”. I’m choosing not to walk through those prerequisites here, because they are already well documented:

  1. Use app-only authentication with the Microsoft Graph PowerShell SDK
  2. Create a self-signed public certificate to authenticate your application

To get started, install the following PowerShell Modules. I should also point out that if you already have these installed, be sure to upgrade to the latest version (1.7.0 at time of writing), since there have been significant changes in how this cmdlet works.

Install-Module Microsoft.Graph.Authentication
Install-Module Microsoft.Graph.Mail
Install-Module Microsoft.Graph.Users.Actions

Once you’ve got those, you can start sending email. Here is a “simple” example that uses a HTML body, as well as uploads a small attachment (attachments above 3MB are more complicated). In the below example, I’m using a sample book1.xlsx file.

#requires -modules Microsoft.Graph.Authentication,Microsoft.Graph.Mail,Microsoft.Graph.Users

#connect with CBA

$ConnectParams = @{
    ClientId = '84af9676-<not real>4194bb6d9e3'
    TenantId = 'ef508849-9d0<not real>5d800549'
    CertificateThumbprint = '96546bf89<not real>67332c703e15123b07'
Connect-Graph @ConnectParams

$EmailAddress  = @{address = ''} #
$Recipient = @{EmailAddress = $EmailAddress}  #

$body  = @{
    content = '<html>hello <b>world</b></html>'
    ContentType = 'html'

# If over ~3MB:
$AttachmentPath = 'C:\tmp\Book1.xlsx'
$EncodedAttachment = [convert]::ToBase64String((Get-Content $AttachmentPath -Encoding byte)) 
$Attachment = @{
    "@odata.type"= "#microsoft.graph.fileAttachment"
    name = ($AttachmentPath -split '\\')[-1]
    contentBytes = $EncodedAttachment

#Create Message (goes to drafts)
$Message = New-MgUserMessage -UserId -Body $body -ToRecipients $Recipient -Subject Subject1 -Attachments $Attachment

#Send Message
Send-MgUserMessage -UserId -MessageId $Message.Id


Once you’re done, the message should look like this in the Sent Items folder of whoever you used to do the sending:

9 thoughts on “Using Send-MgUserMessage to send Email (with Attachments)

  1. Hello Mike,

    Thx for this example script, Microsoft hasn’t made the manual very clear. I have one unexpected issue. I try to send an email to an external email address for the tenant.
    source email:
    email address (target): (other tenant then

    The email returns immediately with this error:
    Your message wasn’t delivered because the recipient’s email provider rejected it.
    Remote Server returned ‘550 5.7.708 Service unavailable. Access denied, traffic not accepted from this IP. For more information please go to AS(7230) [DBXXXXXXXXXX.EURP192.PROD.OUTLOOK.COM]’

    The IP is not blacklisted, but I requested a delist anyway, that did not help.
    When I send from OWA from: to: it works perfectly.

    I have configured the Microsoft Graph SPN permissions and granted these:

    For other purpose the SPN also has:

    Do you have any clue what could fix this?
    Stefan Peters

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s