I used the Send-MailMessage cmdlet a lot in the past for testing Receive Connectors in Exchange or 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 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
For authenticating 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 Certificate Store of the user running the script if you use it for Scheduled Tasks… It would be best if you run it as the user specified in the Scheduled Task.
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
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 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 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)
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