Send Mail with PowerShell and Microsoft Graph API

We all know that the Basic Authentication end is near and that I am a huge fan of Microsoft Graph API, so I am providing an example on “How to send an Email with PowerShell and Microsoft Graph API.”

To learn more from Microsoft GRAPH API, see my Blog Series:
Part 1 – Authentication and Azure App – Use Microsoft Graph API with PowerShell – Part 1 Β» TechGuy
Part 2 – Oauth2.0 – Use Microsoft Graph API with PowerShell – Part 2 Β» TechGuy
Part 3 – First Powershell Script to get a Teams Lis and Walkthrough – Use Microsoft Graph API with PowerShell – Part 3 Β» TechGuy
Part 4 – this one – Use Microsoft Graph API with PowerShell – Part 4 Β» TechGuy

API Reference and Permissions

The official documentation is here: Send mail – Microsoft Graph v1.0 | Microsoft Docs

Azure App Registration Rights:

  • Mail.Send

The Script

$clientID = "yourClientID"
$Clientsecret = "yourSecret"
$tenantID = "yourTenantID"

$MailSender = "michael.seidl@au2mator.com"

#Connect to GRAPH API
$tokenBody = @{
    Grant_Type    = "client_credentials"
    Scope         = "https://graph.microsoft.com/.default"
    Client_Id     = $clientId
    Client_Secret = $clientSecret
}
$tokenResponse = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$tenantID/oauth2/v2.0/token" -Method POST -Body $tokenBody
$headers = @{
    "Authorization" = "Bearer $($tokenResponse.access_token)"
    "Content-type"  = "application/json"
}

#Send Mail    
$URLsend = "https://graph.microsoft.com/v1.0/users/$MailSender/sendMail"
$BodyJsonsend = @"
                    {
                        "message": {
                          "subject": "Hello World from Microsoft Graph API",
                          "body": {
                            "contentType": "HTML",
                            "content": "This Mail is sent via Microsoft <br>
                            GRAPH <br>
                            API<br>
                            
                            "
                          },
                          "toRecipients": [
                            {
                              "emailAddress": {
                                "address": "michael.seidl@au2mator.com"
                              }
                            }
                          ]
                        },
                        "saveToSentItems": "false"
                      }
"@

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

The Result

GitHub Repo

Here you can find the GitHub Repo: Seidlm/Microsoft-Graph-API-Examples (github.com)

Michael Seidl aka Techguy
au2mate everything

36 thoughts on “Send Mail with PowerShell and Microsoft Graph API”

  1. Hello,
    I am receiving the following error:
    “Invoke-RestMethod : The remote server returned an error: (401) Unauthorized.”
    Any idea ? πŸ™‚
    I have looking into for days..
    Thanks πŸ™‚
    Ivan

  2. I set the contentType: “HTML” but get:
    {“error”:{“code”:”BadRequest”,”message”:”Unable to read JSON request payload. Please ensure Content-Type header is set and payload is of valid JSON format.”,

    when I set content: to an html table. The old school send-mailmessage had no issues with this.

  3. You misunderstood:
    “message”: {
    “subject”: “Hello World from Microsoft Graph API”,
    “body”: {
    “contentType”: “HTML”,
    “content”: “This Mail is sent via Microsoft
    GRAPH
    API


    },

    Is what you have. All I am doing is changing the content: to include html table code.

  4. When my mail sender has an on-premise mailbox it fails with Invoke-RestMethod : The remote server returned an error: (401) Unauthorized. If the mail sender has an Exchange online mailbox it works fine and then can send to both on-premise and online mailboxes. We had a hybrid exchange setup and it is working as expected with other applications like Teams etc.

    Any ideas?

  5. Thanks Michael. It does say here for REST API anyway it should be supported. https://docs.microsoft.com/en-us/graph/hybrid-rest-support#requirements-for-the-rest-api-to-work-in-hybrid-deployments. I am just testing with your code in this blog post.

    $clientID = “”
    $Clientsecret = “”
    $tenantID = “”

    $MailSender = “”

    #Connect to GRAPH API
    $tokenBody = @{
    Grant_Type = “client_credentials”
    Scope = “https://graph.microsoft.com/.default”
    Client_Id = $clientId
    Client_Secret = $clientSecret
    }
    $tokenResponse = Invoke-RestMethod -Uri “https://login.microsoftonline.com/$tenantID/oauth2/v2.0/token” -Method POST -Body $tokenBody
    $headers = @{
    “Authorization” = “Bearer $($tokenResponse.access_token)”
    “Content-type” = “application/json”
    }

    #Send Mail
    $URLsend = “https://graph.microsoft.com/v1.0/users/$MailSender/sendMail”
    $BodyJsonsend = @”
    {
    “message”: {
    “subject”: “Hello World from Microsoft Graph API”,
    “body”: {
    “contentType”: “HTML”,
    “content”: “This Mail is sent via Microsoft
    GRAPH
    API


    },
    “toRecipients”: [
    {
    “emailAddress”: {
    “address”: “”
    }
    }
    ]
    },
    “saveToSentItems”: “false”
    }
    “@

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

  6. Hi Michael,
    I am trying send mail api with postman

    endpoint : POST https://graph.microsoft.com/v1.0/users/$MailSender/sendMail

    Header:

    Content-Type:application/json
    Content-Length:0

    Body :
    {
    “message”: {
    “subject”: “Hello World from Microsoft Graph API”,
    “body”: {
    “contentType”: “HTML”,
    “content”: “This Mail is sent via Microsoft ”
    },
    “toRecipients”: [{
    “emailAddress”: {
    “address”: “—-@—-”
    }
    }]
    },
    “saveToSentItems”: “false”
    }

    When I hit the send button I am getting below message as a response

    response : Bad request 400
    {
    “error”: {
    “code”: “ErrorInvalidParameter”,
    “message”: “The value of the parameter ‘Message’ is empty.”
    }
    }

    though my message parameter is not empty in body. Still getting the error for message.
    I am following https://docs.microsoft.com/en-us/graph/api/user-sendmail?view=graph-rest-1.0&tabs=http
    Kindly assist.

    Thanks,
    Priya

  7. Hi
    Do you know if it’s possible to have parameter with waiting for Delivery receipt ?

  8. Hi,
    The parameter can be set to receive a Delivery receipt, the logic to wait for needs to be scripted in PowerSehll.
    We can help on this, just let me know

  9. Hi Michael,

    I am getting the below error relating to the invoke command. Do you know how I might overcome this?

    Invoke-RestMethod : The remote server returned an error: (400) Bad Request.

    Many thanks

  10. THANK YOU. I was hung up on finding an actual PowerShell JSON example that worked and got yours plugged into my almost-done script and got to finish line. Appreciate it πŸ™‚

  11. very nice option to send mail messages from powershell… thank you for that! One question, how can i send to multiple recipients?

  12. Hi, please see the example for BCC here, do the same for Recipient


    "message": {
    "subject": "$Subject",
    "body": {
    "contentType": "HTML",
    "content": "$Body
    "
    },
    "toRecipients": [
    {
    "emailAddress": {
    "address": "$TO"
    }
    }
    ],
    "bccRecipients": [
    {
    "emailAddress": {
    "address": "$Bcc1"
    }
    },
    {
    "emailAddress": {
    "address": "$Bcc2"
    }
    }
    ],
    },

  13. Hello, if we want to send the same mail several time in a for loop and and in subject “test N1 and increment automatically each time it’s called”, where do we add the loop?

  14. how it will increment the subject number?
    example test 1, test 2, test 3 (as subject each time a mail is sent)?

  15. I know how a loop works… my problem is how to increment a number [$i] in the subject that’s all. If you don’t know how to do it, just tell it, but do not provide me article to explain how a loop is working.

    My problem is the BodyJsonSend
    $BodyJsonsend = @”
    {
    “message”: {
    “subject”: “Test Mail $($i)”,
    “body”: {
    “contentType”: “HTML”,
    “content”: “This Mail is sent via Microsoft
    GRAPH
    API


    },
    “toRecipients”: [
    {
    “emailAddress”: {
    “address”: “email@domain.com”
    }
    }
    ]
    },
    “saveToSentItems”: “false”
    }
    “@
    For($i = 0;$i -lt 10;$i++)
    {
    Invoke-RestMethod -Method POST -Uri $URLsend -Headers $headers -Body $BodyJsonsend
    }

  16. Hi, if you know how to loop, you should be able to send it.
    I would recommend creating a Function to send the Mail and pass the Subject to the Function

    In your example, add the $BodyJsonsend in the for Loop, then it should work.

  17. hi, i am getting an Error while sending Mail with Graph API. IT says Message ist empty, but when i Copy my requests top Graph Explorer IT will Work fine.

  18. Sorry for the long code, but hope you can find this error:
    {“error”:{“code”:”ErrorInvalidParameter”,”message”:”The value of the parameter ‘Message’ is empty.”}}

  19. Hi Michael, thanks so much for posting mine is working as expected. I would like to email some .CSV attachments with it to multiple email addresses. Could you provide the code to add please.

  20. Oh so sorry, I have just seen the post about. let me check out that link and get back to you if need be

  21. Thank you! The first Script I’ve come across that actually works, after spending countless hours trying to achieve this.

Leave a Comment

Your email address will not be published. Required fields are marked *

*