The Correct Way To Send Mail In PowerShell

Send Mail In PowerShell

Are you still using Send-MailMessage to Send Mail In PowerShell? You need to stop. The command needs SMTPAuth enabled for your organization. If you are looking for ways to security harden you M365 tenant, disabling this feature is a good way to go. But you still need to send email in PowerShell, right? I will show you in three steps.

Step One – Send Mail In PowerShell (Set up an App is Azure)

The first step involves setting up an App registration that will let you send mail. Create an App Registration in Azure Ad by going to Azure AD / Application / App Registrations and creating one:

Send Mail In PowerShell

Click register. Now that you have you App for sending mail registered, go to API Permission and give the App permissions to Send mail as any user.

Send Mail In PowerShell

Please don’t forget to click on “Grant admin consent for” on the app.

To finish our Azure App, we need to configure the Authentication Method to use as a Client Secret. Navigate to “Certificates & secrets” and select “New client secret.”

Send Mail In PowerShell

Enter a Name and Expire Date. Not this date because when it expires, your scripts that use this app will stop working and you will have to renew it.

Send Mail In PowerShell


When you click “Add”, the Secret is created and you have a unique chance to get the Client Secret. This is a one-time shot, so copy the Secret, before refreshing the Page or navigating to a different Section.

Send Mail In PowerShell

Now on to step two.

Step Two – Send Mail In PowerShell (Set Security Group in Exchange Online)

Once you are done creating an App, you need to set and application policy that will only let you use only the email address you specify in your organization to send mail as:

Connect to Exchange-Online and then run the following command in PowerShell:

  1. Connect to Exchange Online with the ExchangeOnlineManagement PowerShell module Connect-ExchangeOnline
  2. Create a mail enabled security group which contains all the accounts you want to send mails from $restrictedGroup = New-DistributionGroup -Name “Mail service accounts” -Type “Security” -Members @(“[email protected]”)
  3. Optionally hide the group from the address list Set-DistributionGroup -Identity $restrictedGroup.Identity -HiddenFromAddressListsEnabled $true
  4. Create the application access policy to only allow sending the app mails for the specified distribution group
  5. Run this last set of commands:

$params = @{

    AccessRight        = “RestrictAccess”

    AppId              = “1f5ffbea-f13f-4f1a-af63-258ce4344daf”

    PolicyScopeGroupId = $restrictedGroup.PrimarySmtpAddress

    Description        = “Restrict app permissions to only allow access to service account”


New-ApplicationAccessPolicy @params

Once this group is created you can go to into in (Admin portal) and Navigating to Users / Teams & Groups / Mail Enabled Security Groups and making changes as necessary:

Send Mail In PowerShell

When you send mail using MS Graph, only the email address list above will be the only one able to send as.

Step Three – Send Mail In PowerShell (Use MS Graph in PowerShell)

In order to send mail in this new set up, you need to take note of three pieces of information from your app registration:

  • Tenant ID – you can get it by looking here
  • Client Secret (NOTE:) from above
  • App (Client ID) – you need to got to the listing of your app registration and you App (Client ID will be listed here (See below)
Send Mail In PowerShell

Then, use this script to send your mail:

#Declare Parameters

$clientID = “your ID from App Registration”
$clientSecret = “your client secret from App Registration”
$tenantID = “your tenant ID”

#Run Script

$MailSender = “[email protected]

#Connect to GRAPH API

$tokenBody = @{
Grant_Type = “client_credentials”
Scope = “”
Client_Id = $clientId
Client_Secret = $clientSecret
$tokenResponse = Invoke-RestMethod -Uri “$tenantID/oauth2/v2.0/token” -Method POST -Body $tokenBody
$headers = @{
“Authorization” = “Bearer $($tokenResponse.access_token)”
“Content-type” = “application/json”

#Send Mail

$URLsend = “$MailSender/sendMail”
$BodyJsonsend = @”
“message”: {
“subject”: “Hello World from Microsoft Graph API”,
“body”: {
“contentType”: “HTML”,
“content”: “This Mail is sent via Microsoft



                      "toRecipients": [
                          "emailAddress": {
                            "address": "[email protected]"
                    "saveToSentItems": "false"


Invoke-RestMethod -Method POST -Uri $URLsend -Headers $headers -Body $BodyJsonsend


It seems like a lot of work but this is just to set it up. Now that you have a good base, whenever you need to send a mail for whatever reason in PowerShell all you have to do is make sure the required email sender address is in the Mail Enabled Security Group and in the variable in the script and you are good to go. A good example is notifying users that they are using external forwarding!

Happy IT’ing


Avatar photo

I am an IT professional with over twenty years experience in the field. I have supported thousands of users over the years. The organizations I have worked for range in size from one person to hundreds of people. I have performed support from Help Desk, Network / Cloud Administration, Network Support, Application Support, Implementation and Security.

Pin It on Pinterest