How to Send an Email via MailGun API using PowerShell 7

Mailgun is an email sending service that provides logging and an API to send emails. PowerShell is particularly strong in its ability to use REST API’s. There are many use cases for needing to send emails, but one of the most common is that of sending emails when scripts are completed. This may be for status updates or failures.

With that in mind, how do we set up MailGun for use with PowerShell and send emails as we need them? In this article, we will explore this use case and how best to create a simple script to send an email using MailGun.

Setting Up Mailgun

Once you have created a Mailgun account, there are a few simple steps. Below are the next two steps to configure.

  • Adding your Domain to send email from
  • Retrieving API Key

    Add a Domain

    Navigate to Sending → Domains and click on Add New Domain. Create the domain as follows:

    Image # Expand
    Untitled 56 1

    Upon clicking Add Domain, you will be brought to a screen listing all of the corresponding DNS records that you will need to be entered in whichever DNS provider you have. Once all those settings have been added, and you have verified your DNS settings, we can retrieve the API key.

    Retrieving the API Key

    Unlike many other API’s, Mailgun does not use Tokens, but a single API key for all services. Navigate to Account → Settings and choose API Keys. Click on API Security and view the Private API Key. This will be the key we use to authenticate and send emails via PowerShell.

    Creating PowerShell Script

    Like many other API’s we will use the familiar Invoke-RestMethod method to actually create the HTTP call to send the email via API. The authentication method to use is Basic Auth, with the API header key. Additionally, we will create an object to hold our data but pass this in via the Form parameter which is using multi-part/formdata. This is different than other API’s which typically uses JSON.

    What are the fields that are required and optional? Below we take a look at what is needed, and then what are some of the other available options. More settings are available in the Mailgun API documentation.

    Required

    • From
    • To
    • Subject
    • Text

          Optional

          Though we don’t list all of the optional fields here, these are some of the more interesting and useful ones.

          • CC & BCC
          • HTML
          • attachment (must use multi-part/formdata
          • inline (can be used to send inline images)
            • o:testmode – If set to true, Mailgun will accept the message but it will not be sent. Keep in mind that you are still charged for the message (unless under the free limit).
            • o:deliverytime – If configured, you can set a future delivery time for up to 3 days in advance for the future. Mailgun uses the rfc2822 date format.

                    Finally, let’s create a simple script to send a basic, non-HTML message, using the MailGun API.

                    $APIKey = 'key-asdf887as8fa8df8a7df87sd8f8sa8sd'
                    
                    $Params = @{
                      "URI"            = 'https://api.mailgun.net/v3/mail.mydomain.com/messages'
                      "Form"           = @{
                        "from"    = '[email protected]'
                        "to"      = '[email protected]'
                        "subject" = 'Test Email'
                        "text"    = 'Test Text!'
                      }
                      "Authentication" = 'Basic'
                      "Credential"     = (New-Object System.Management.Automation.PSCredential ("api", ($APIKey | ConvertTo-SecureString -AsPlainText)))
                      "Method"         = 'POST'
                    }
                    
                    Invoke-RestMethod @Params
                    ?
                    You can even send amp-html messages using the amp-html parameter. You would need to follow the Google guidelines.

                    Verifying the Sent Email

                    One of the great features of Mailgun is the ability for it to log messages, by default the past 7 days for free accounts, and you can use that to see if the message was sent and the response by receiving mail systems.

                    Click on Sending → Logs and make sure you have chosen the correct domain from the dropdown. Once here, you will see a list of messages and their various statuses below. You can click on any individual one to learn more about the data being sent and it’s metadata which can be invaluable for troubleshooting.

                    Image # Expand
                    Untitled 57

                    Extending our Script

                    Now that we have sent a simple email, oftentimes we want to create a nicer looking email that may use HTML formatting and send an attachment.

                    As stated before, an attachment must use the multi-part/formdata, and by using the Form parameter on Invoke-RestMethod we are already sending this data in the correct format. So how do we get an attachment to send then? By retrieving the data and assigning it to our form variable we can then send the attachment.

                    $APIKey = 'key-asdf887as8fa8df8a7df87sd8f8sa8sd'
                    
                    $Params = @{
                      "URI"            = 'https://api.mailgun.net/v3/mail.listekconsulting.biz/messages'
                      "Form"           = @{
                        "from"    = '[email protected]'
                        "to"      = '[email protected]'
                        "subject" = 'Test Email'
                        "text"    = 'Test Text!'
                        "attachment" = Get-Item -Path 'C:\Temp\Test.txt'
                      }
                      "Authentication" = 'Basic'
                      "Credential"     = (New-Object System.Management.Automation.PSCredential ("api", ($APIKey | ConvertTo-SecureString -AsPlainText)))
                      "Method"         = 'POST'
                    }
                    
                    Invoke-RestMethod @Params

                    You can track this the same as before by navigating to the logs within Mailgun and noting the result of the API call and see that the attachment sent as expected. If you expand the log information, you can see if the attachment was accepted and other details pertaining to the email that was sent.

                    Image # Expand
                    Untitled 58

                    There are a few statuses to watch for, such as Accepted, Delivered, or Opened (if click-tracking is turned on). Ultimately, you are looking for Delivered to make sure the email actually made it.

                    Conclusion

                    Mailgun is an invaluable tool for sending emails as it has a generous free limit with logging. This is unusual in other services that offer email sending services. With a robust API and excellent integration into multiple languages, it is an easy choice to integrate into your PowerShell scripts.

                    To take this even further, it would be common to then turn this into a module by wrapping the functionality with validation and error checking. By doing this, you can easily integrate Mailgun into your entire script pipeline and infrastructure. PowerShell 7 makes this process better, by extending the Invoke-RestMethod cmdlet with easy form data handling which in the past used to be troublesome.

                    Related Article: