Using Send-MgUserMail as the Send-MailMessage replacement

I used the Send-MailMessage cmdlet a lot in the past for testing Receive Connectors in Exchange or for emailing 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 there is no immediate replacement available in PowerShell, we recommend you do not use Send-MailMessage at this time. 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 for local Exchange installations or any other service running SMTP.

Preparations

(Self-Signed) Certificate

For authenticating Microsoft Graph, you can use a self-signed certificate which you can create 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 in the Certificate Store of the user running the script, if you use it for Scheduled Tasks… You should run it as the user specified in the Scheduled Task of course.

Note: For testing/personal use, it’s ok to use a Self-Signed certificate 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

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

  • Go to App Registrations
  • Select New Registration
  • Enter ‘Graph Email’ (For example, choose your own preferred one) as Name and select Register
  • Make note of 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
  • Make note of the Thumbprint by right-clicking the Thumbprint line and selecting 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 select 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 for connecting to 365. For This you need to have to 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 own values)

Select-MgProfile -Name "Beta"
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

Leave a Reply

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