-
Notifications
You must be signed in to change notification settings - Fork 0
Send mail from an Outlook.com account
In this example, we will use New-MSGraphAccessToken
to obtain an access token including the mail.send scope (i.e. delegated permission), and we'll do so using the Device Code authorization flow. There is no pre-setup required, other than having an Outlook.com account and Windows PowerShell 5.1 (or PowerShell Core 6+). Once we have the access token in hand, we'll use New-MSGraphRequest
to send our sendMail
request to Microsoft Graph. The message will be sent from your Outlook.com account just as though you had sent it using OWA or the Outlook desktop client.
ℹ To save you needing to create your own application in your own Azure AD, I'll supply you with the ApplicationId from my MSGraphPSEssentials application, which is registered as a multi-tenant app in my Azure AD tenant. Don't worry, you aren't granting me or my Azure AD tenant access to your Outlook.com account by using my app. Rather, you'll be the only one with the access token (and refresh token, optionally) and your PowerShell session is where all activity will be carried out. Once finished, simply close your PowerShell console and wipe the permissions off your Outlook.com account via https://microsoft.com/consent.
Install-Module MSGraphPSEssentials -Scope CurrentUser
If you've never installed a module this way, you will be prompted to approve a couple of things, as the PSGallery repository won't be configured as Trusted. We've chosen to install the module into the CurrentUser scope, so no administrative access will be required.
$TokenObject = New-MSGraphAccessToken -ApplicationId '0c26a905-7c94-4296-aeb4-b8925cb7e036' -Scopes mail.send
Follow the instructions, which should look something like this:
Authorization started (expires at 2020-12-19 03:01:44 PM)
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code FB228GRH7 to authenticate.
[D] Done [?] Help (default is "D"):
At this point, we can look to the Microsoft Graph reference page for the sendMail method: https://docs.microsoft.com/en-us/graph/api/user-sendmail?view=graph-rest-1.0&tabs=http. We'll focus on the request body section of said page for now. The request headers will be handled automatically by New-MSGraphRequest
in the next step):
In the request body, provide a JSON object with the following parameters.
Parameter Type Description message Message The message to send. Required. saveToSentItems Boolean Indicates whether to save the message in Sent Items. Specify it only if the parameter is false; default is true. Optional.
So, we'll need to prepare a JSON object containing a Message object, which just so happens to be another JSON object, which we'll nest into our request body. To see all available properties that can be specified on a Message object, check the JSON representation section of the Message page.
For our example, we'll keep it simple:
$requestBody = @{
message = @{
subject = 'MS Graph sendMail Test'
body = @{
contentType = 'text'
content = "This is a test message, sent using MS Graph's sendMail method."
}
toRecipients = @(
@{
emailAddress = @{
address = 'Bill.Gates@contoso.com'
}
},
@{
emailAddress = @{
address = 'Satya.Nadella@contoso.com'
}
}
)
attachments = @(
@{
'@odata.type' = '#microsoft.graph.fileAttachment'
name = 'Screenshot.png'
contentBytes = "$([Convert]::ToBase64String([System.IO.File]::ReadAllBytes(""$HOME\Desktop\Screenshot.png"")))"
}
)
}
}
Pretty simple stuff. Just a hashtable with some properties within, and for any properties which have nested properties, we supply those as nested hashtables. We'll convert this multi-level hashtable to JSON in the next step.
💡 Bonus Tip: I included two recipients to show how to do that, and also added an attachment.
With the Message object ready to go, we can now change our focus to the HTTP request section of the sendMail reference page:
POST /me/sendMail POST /users/{id | userPrincipalName}/sendMail
This tells us we need to use the POST HTTP method and gives us two options for where we can send our request. In our case, using Outlook.com, the only option that makes sense is this one: /me/sendMail
. If we were using an app-only token with the necessary application permissions granted in an Azure AD tenant, we could specify the Azure AD ObjectId of any user with an EXO mailbox and send the message as them (e.g. /users/c34aabd6-9d4d-4fe7-a082-1720f7cc2cc5/sendMail
).
So here we go, we'll now send our request using New-MSGraphRequest
with all of the details we've covered/prepared above:
New-MSGraphRequest -Request '/me/sendMail' -AccessToken $TokenObject -Method POST -Body (ConvertTo-Json $requestBody -Depth 5)
And there you have it, message sent! Notice how for the body, we converted the $requestBody
hashtable to JSON. The reason we specify -Depth 5
is that, by default, ConvertTo-Json
only captures two levels deep. In our $requestBody
, the deepest property is address, at a depth of 3. You can, and I like to, specify a depth that is deeper than necessary, up to the maximum of 100.