Using Send-MgUserMail as the Send-MailMessage replacement

I have often used the Send-MailMessage cmdlet to test Receive Connectors in Exchange or email reports in scheduled PowerShell scripts. When you try to use the Send-MailMessage cmdlet, it has been showing you this message for quite a while now:

WARNING: The command ‘Send-MailMessage’ is obsolete. This cmdlet does not guarantee secure connections to SMTP servers. While no immediate replacement is available in PowerShell, we recommend you not use Send-MailMessage. See https://aka.ms/SendMailMessage for more information.

In this blog post, I will show you the new way of sending emails using Send-MgUserMail.

Note: This works for Exchange Online, not local Exchange installations or any other SMTP service.

Preparations

(Self-Signed) Certificate

To authenticate Microsoft Graph, you can use a self-signed certificate, which you can create by running the following lines in PowerShell. The certificate file will be in c:\temp, and its name will be like the $certname variable, in this case, “SendEmail.cer”. The lines below will import the certificate into the user’s Certificate Store running the script if you use it for Scheduled Tasks… It would be best to run it as the user specified in the Scheduled Task.

Note: For testing/personal use, using a Self-Signed certificate is okay, but I strongly advise using a corporate certificate.

$certname = "SendEmail"
$cert = New-SelfSignedCertificate -Subject "CN=$certname" -CertStoreLocation "Cert:\CurrentUser\My" -KeyExportPolicy Exportable -KeySpec Signature -KeyLength 2048 -KeyAlgorithm RSA -HashAlgorithm SHA256
Export-Certificate -Cert $cert -FilePath "C:\Temp\$certname.cer"

Registering an App for authentication

To connect to Microsoft Graph, you have to authenticate first, of course. If you register an app, you can use the IDs in your scripts. Steps are:

  • Go to App Registrations
  • Select New Registration
  • Enter ‘Graph Email’ (For example, choose your preferred one) as Name and select Register
  • Note the Application (client) ID and the Directory (tenant) ID.
  • Select Certificates and secrets
  • Select Certificates
  • Select Upload certificate
  • Select the folder icon on the Select a file line and browse to your certificate from the previous step.
  • Enter “SendEmail” (For example) as the description and select Add
  • Please make a note of the Thumbprint by selecting the Thumbprint, right-clicking it, and selecting the Copy
  • Select API permissions
  • Select Add a permission
  • Select Microsoft Graph
  • Select Application permissions
  • Enter “mail.send” in the search box, select “Mail.Send” and Add Permission.
  • Select Grant admin consent for… and select Yes

Sending an email using Send-MgUserMail

Now that the authentication part is done, you can start using it to connect to 365. For this, you need to have Microsoft.Graph module installed on your system, you can do this by running:

Install-Module Microsoft.Graph
Import-Module Microsoft.Graph

Now that the module is installed, you can send an email with an attachment (c:\temp\output.csv in this example) by running: (Change the XXXX, From, To, Subject, Body, and attachment variable to your values)

Connect-MgGraph -ClientId XXXX -TenantId XXXX -CertificateThumbprint XXXX -ContextScope CurrentUser

$from = "admin@Mpowershellisfun.com"
$to = "harm@powershellisfun.com"
$subject = "PowerShell is fun :)"
$type = "html"
$body = "See attached file"
$attachment = "c:\temp\output.csv"
$FileName = (Get-Item -Path $Attachment).name
$base64string = [Convert]::ToBase64String([IO.File]::ReadAllBytes($Attachment))
  
$recipients = @()
$recipients += @{
    emailAddress = @{
        address = $To
    }
}

$message = @{
    subject      = $subject
    toRecipients = $recipients
    Attachments  = @{
        name         = $FileName
        contenttype  = 'text/plain'
        contentbytes = $base64string
    }
    body         = @{
        contentType = $type
        content     = $body
    }
}
 
Send-MgUserMail -UserId $from -Message $message

More information about Send-MgUserMail can be found here

3 thoughts on “Using Send-MgUserMail as the Send-MailMessage replacement

  1. Can I use this in Azure runbook? Tried to but getting errors. Microsoft Grap Module is loaded.
    The specified module ‘Microsoft.Graph’ was not loaded because no valid module file was found in any module directory.
    ‘CertificateThumbprint’ must have a length of 40. Ensure you have the right certificate thumbprint then try again.
    System.Management.Automation.CommandNotFoundException: The term ‘body’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

    1. This example uses a certificate and thumbprint from your local certificate store. For an Azure RunBook, you need to authenticate differently… (Haven’t tried that yet to be honest)

Leave a Reply to Harm VeenstraCancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.