How to send emails through Microsoft 365 from PowerShell
If you’re like me, you probably have a ton of scripts that manage different parts of your Microsoft 365 tenants. I monitor these scripts by sending myself an email after these script run and then I check my inbox to make sure they ran successfully.
With basic authentication being deprecated in Microsoft 365 you may be having issues sending emails through PowerShell scripts. But that's not the only issue Microsoft is also deprecating send-mailmessage in PowerShell.
Another problem is MFA. Maybe your organization requires MFA for all the user accounts. You can't expect to sign in using MFA every time you want the script to run and send an email! That would be ridiculous.
Fortunately, we haven't been left without an option. There is a little more setup to do to get going though. Here’s a quick overview
- Register an app in the Microsoft Entra admin center
- Assign permissions so the app can send emails
- Create a self-signed certificate on the computer where we’ll be sending the emails
- Upload the certificate to our Microsoft Entra app
- Install the MG Graph PowerShell module
- Create and run the script
So let’s dive right in.
Register an app in the Microsoft Entra admin center
As I mentioned above we'll need to register an app in Microsoft Entra.
- Go to Microsoft Entra admin center > Applications > App registrations > New registration.
- Set the name to Allow sending emails then click Register.
Assign permissions so the app can send emails
Next, we'll need to grant our app permission to send emails.
- From your registered app click API permissions > Add a permission > Microsoft Graph
- Select Application permissions > find and expand Mail in the Permission list > Check Mail.Send > Add permissions.
- Click Grant admin consent > Yes
Create a self-signed certificate on the computer where we’ll be sending the emails
Now we'll need to jump to the computer or server where we are sending the emails and create a self-signed certificate.
- Open PowerShell as an admin.
- Run the following command (replace gruber18.onmicrosoft.com with your tenant): $Cert = New-SelfSignedCertificate -DnsName 'gruber18.onmicrosoft.com' -CertStoreLocation "Cert:\CurrentUser\My" -FriendlyName "Send_Emails" -KeySpec Signature -NotAfter (Get-Date).AddYears(5)
- Run the following command: Get-ChildItem "Cert:\CurrentUser\my\$($Cert.Thumbprint)" | Export-Certificate -FilePath C:\graph.cer
Upload the certificate to our Microsoft Entra app
Next, we'll upload the certificate to our registered Microsoft Entra app. That way Microsoft can compare the certificate we uploaded to the certificate we'll use during the sending of the email messages.
- Go to Microsoft Entra admin center > Applications > App registrations > Click Allow sending emails.
- Click Certificates & secrets > Certificates > Upload certificate > Select your certificate from C:\graph.cer in the Upload a certificate box. Enter a description. Click Add.
Install the MG Graph PowerShell module
The last step before we can send emails using PowerShell! We simply need to install the MG Graph PowerShell module. This is the module we'll use to send emails through PowerShell.
- Open PowerShell as an administrator.
- Run Install-Module Microsoft.Graph
- Click Y then press Enter. Click Y then press Enter.
Create and run the script
Finally, we've done all the prep work. We've created an app and given it the correct permissions. We've created a certificate and uploaded it to our registered app. We've installed the Graph PowerShell module. Now, we can send emails through PowerShell!
- Go back to your registered app in the Microsoft Entra admin center. Click Overview.
- Copy the Application (client) ID and Directory (tenant) ID.
- Click Certificate & secrets. Copy the thumbprint.
- Enter the following PowerShell replacing the ClientId, TenantId, CertThumbprint, address, and UserId with your information.
$ClientId = '65bf8b60-3552-4621-ab36-9b6e7072093e'
$TenantId = 'd01acbb1-ad7d-48bc-b82d-7597ca77ca95'
$CertThumbprint = '1F4B63E994D8513DE582A50B327A52F2C90C7551'
$Message = @{
subject = "Hello World!";
toRecipients = @(@{
emailAddress = @{
address = "admin@gruber18.onmicrosoft.com";
}});
body = @{
contentType = "text";
content = "This is my test email."
}
}
Connect-MgGraph -ClientId $ClientId -TenantId $TenantId -CertificateThumbprint $CertThumbprint
Select-MgProfile -Name v1.0
Send-MgUserMail -UserId "John@gruber18.onmicrosoft.com" -Message $Message