Send Mail with Attachment via Microsoft Graph

Send Mail with Attachment via Microsoft Graph

Hi All,

I had to debug an Application that sends a Mail with an Attachment via Graph API. I’ve created this Small Script to Test the Functionality.

Entra Application

You need an Entra Application.

Entra Application:

Certificate Authentication:

Permissions:

  • Application: Mail.ReadWrite
  • Application: Mail.Send

Application Access Policy

I’ve written a whole Article Application Access Policy in Exchange Online

Connect-ExchangeOnline -ShowBanner:$False
Get-DistributionGroup -Identity PostmasterGraphRestriction | fl DisplayName, PrimarySmtpAddress, ExternalDirectoryObjectId
Get-DistributionGroupMember -Identity PostmasterGraphRestriction | fl DisplayName, PrimarySmtpAddress,ExternalDirectoryObjectId

With this Application Access Policy you restrict the Graph Permissions of the Entra Application to the Members of the Distribution Group.

New-ApplicationAccessPolicy -AccessRight RestrictAccess -AppId "5cf8b5b9-1532-44bf-9e39-5f70534a2e90" -PolicyScopeGroupId "PostmasterGraphRestriction@icewolf.ch" -Description "Restrict this app to members of this Group"

Send Attachment via Graph API

Now we come to the Part where we send a Mail with an Attachment. It involves multiple steps:

  • Create the Message (in Drafts)
  • Add the Attachment (in Drafts)
  • Send the Draft Message

First we need to Connect with the Graph API

###############################################################################
# Variables
###############################################################################
$AppID = "5cf8b5b9-1532-44bf-9e39-5f70534a2e90" #DemoSendAttachment
$TenantId = "icewolfch.onmicrosoft.com"
$CertificateThumbprint = "A3A07A3C2C109303CCCB011B10141A020C8AFDA3" #O365PowerShell4
Connect-MgGraph -ClientId $AppID -TenantId $TenantId -CertificateThumbprint $CertificateThumbprint -NoWelcome

Let’s create the Draft Message

###############################################################################
# Create Mailbox Message
# https://docs.microsoft.com/en-us/graph/api/user-post-messages?view=graph-rest-1.0&tabs=http
###############################################################################
$Mailbox = "Postmaster@icewolf.ch"
$URI = "https://graph.microsoft.com/v1.0/users/$Mailbox/messages"
 
$ContentType = "application/json"
$Headers = @{"Authorization" = "Bearer "+ $AccessToken}
$Body = @"
{
    "subject":"Demo Attachement",
    "body":{
        "contentType":"HTML",
        "content":"Look at the <b>awesome</b> attachment!"
    },
    "toRecipients":[
        {
            "emailAddress":{
                "address":"a.bohren@icewolf.ch"
            }
        }
    ]
}
"@
$Result = Invoke-GraphRequest -URI $URI -Method POST -Body $Body -ContentType $ContentType
$MessageID = $Result.id
$MessageID

this is the Drafts Message in Outlook on the Web

Let’s add the Attachment. Note that the Content needs to be loaded as Bytearray and then convert to Base64

###############################################################################
# Add Attachment to Mailbox Message (max 3MB)
# https://docs.microsoft.com/en-us/graph/api/message-post-attachments?view=graph-rest-1.0&tabs=http
###############################################################################
$URI = "https://graph.microsoft.com/v1.0/users/$Mailbox/messages/$MessageID/attachments"

#Get Byte Content
If ($host.version -ge "7.0")
{
    #PowerShell 7
    $ContentByte = Get-Content -Path "C:\Temp\AndresBohren.jpg" -AsByteStream
} else {
    #PowerShell 5
    $ContentByte = Get-Content -Path "C:\Temp\AndresBohren.jpg" -Encoding Byte
}

#Convert to Base64
$Base64 =[Convert]::ToBase64String($ContentByte)

$ContentType = "application/json"
$Headers = @{"Authorization" = "Bearer "+ $AccessToken}
$Body = @"
{
  "@odata.type": "#microsoft.graph.fileAttachment",
  "name": "AndresBohren.jpg",
  "contentBytes": "$Base64"
}
"@

$Result = Invoke-GraphRequest -URI $URI -Method POST -Body $Body -ContentType $ContentType

The File is now attached to the Draft Message

Now, we can send the Message

###############################################################################
# Send draft message
# https://learn.microsoft.com/en-us/graph/api/message-send?view=graph-rest-1.0&tabs=http
###############################################################################
$URI = "https://graph.microsoft.com/v1.0/users/$Mailbox/messages/$MessageID/Send"
$Result = Invoke-GraphRequest -URI $URI -Method POST 

This is the Message i received in Outlook Classic

Summary

Now you have learned how the send an Mail with Attachment via the Graph Api and PowerShell. Hope you find this useful.

Regards
Andres Bohren

Exchange Logo

PowerShell Logo