Sending emails via Microsofts Graph API
Christopher Talke Buscaino
If you need to send emails from a shared mailbox using the Graph API, there’s a key thing to know up front:
- The mailbox must be licensed if you’re accessing it via an application flow (not delegated).
- There’s no workaround for hitting endpoints like
/messages
or/mailFolders
without a license, this is just how the API works using the application flow.
Below is a quick and dirty PowerShell script to get you going.
It requires the following permissions: Mail.ReadWrite, Mail.Send, and MailboxSettings.Read
👋 Enjoy
$tenantId = ""
$clientId = ""
$clientSecret = ""
$fromUser = ""
$toUser = ""
try {
$body = @{
grant_type = "client_credentials"
scope = "https://graph.microsoft.com/.default"
client_id = $clientId
client_secret = $clientSecret
}
$tokenResponse = Invoke-RestMethod -Method Post -Uri "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" -Body $body
$accessToken = $tokenResponse.access_token
$headers = @{ Authorization = "Bearer $accessToken" }
$mailboxSettings = Invoke-RestMethod -Method Get -Uri "https://graph.microsoft.com/v1.0/users/$fromUser/mailboxSettings" -Headers $headers
$mailboxSettings | Format-List
$emailBody = @{
message = @{
subject = "Test Email from App"
body = @{
contentType = "Text"
content = "This is a test email sent using Microsoft Graph with application permissions."
}
toRecipients = @(
@{
emailAddress = @{
address = $toUser
}
}
)
}
saveToSentItems = $true
}
Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/users/$fromUser/sendMail" -Headers $headers -Method POST -Body ($emailBody | ConvertTo-Json -Depth 10) -ContentType "application/json"
Write-Host "Email sent from $fromUser to $toUser"
}
catch {
Write-Host "Error occurred with user endpoint, trying alternative..." -ForegroundColor Yellow
Write-Host "Status Code: $($_.Exception.Response.StatusCode.value__)" -ForegroundColor Red
$streamReader = [System.IO.StreamReader]::new($_.Exception.Response.GetResponseStream())
$errorContent = $streamReader.ReadToEnd() | ConvertFrom-Json
Write-Host "Error Details: $($errorContent.error.message)" -ForegroundColor Red
Write-Host "Error Code: $($errorContent.error.code)" -ForegroundColor Red
}