Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
App-Only Authentication with Exchange in Azure Automation

App-Only Exchange Online Authentication with Azure Automation

Introduction

Basic Authentication is deprecated and will not be available to new tenants starting October 2020 and will be removed from existing tenants in 2H 2021.

What does this mean for your Azure Automation Scripts that connect to Exchange Online? It means they'll stop working! How about you get on the ball now and get it working.

Did you know the Azure Automation RunAs account is a service principal? This means that it can do everything a service principal can do, including authentiate to Exchange Online using the certificate it autogenerates.

Notice: This article is intended for legacy scripts that must run on Azure Automation. You really should consider moving to Azure Functions Powershell if you are doing things net-new, and yes, you can call Powershell 5.1 from the Powershell 7 runtime in Azure Functions so there's no reason you should need to stick with Azure Automation for compatibility.

If you want to set up something similar for applications other than Azure AD, check out the PSServicePrincipal module and its README

Exchange Online Management 2.0.3-Preview

You will need the ExchangeOnlineManagement 2.0.3 or greater imported into your Azure Automation environment. As of this writing it was still a prerelease. This command will install the module directly from the Powershell Gallery to your Azure Automation Account

#Requires -Module Az.Automation
New-AzAutomationModule -ResourceGroupName 'MyAAResourceGroupName'  -AutomationAccountName 'MyAutomationAccountName' -Name 'ExchangeOnlineManagement' -ContentLinkUri 'https://www.powershellgallery.com/api/v2/package/ExchangeOnlineManagement/2.0.3-Preview'

image

Configure Azure Automation RunAs Account for Exchange Access

The Azure Automation RunAs account (aka an Azure AD Service Principal) can behave the same as any user in Azure AD, including managing Exchange, Sharepoint, etc. as long as permissions are assigned. For the scope of this article we will grant the Exchange Administrator role to the runas account. In a real production environment, you should instead use role assignment policies to limit the scope of your runas account to only what it needs to do.

Run this command from a system with AzureAD, Az.Account, and Az.Automation Modules installed

**NOTE: Due to an api limitation this script assumes you are using the default RunAs Account. **

#requires -module AzureAD,Az.Automation,Az.Resources
$aaInfo = @{
    ResourceGroup = 'MyAAResourceGroup'
    AutomationAccountName = 'MyAutomationAccountName'
}

$aaConnection = Get-AzAutomationConnection @aaInfo -Name 'AzureRunAsConnection'
$aaRunAsServicePrincipal = Get-AzAdServicePrincipal -DisplayNameBeginsWith $aaConnection.AutomationAccountName
$ESARole = Get-AzureADDirectoryRole | where displayname -eq 'Exchange Service Administrator'
Add-AzureAdDirectoryRoleMember -ObjectId $ESARole.objectid -RefObjectId $aaRunAsServicePrincipal.Id

You can also do this via the Azure Portal:

image

Connect to Exchange in Runbook

Add this to your runbook. The automation account automatically puts the runas certificate in the CurrentUser certificatestore, so no need to do any fancy retrieval via Get-AutomationCertificate. Once connected you can run exchange commands and the new "EXO" commands as normal

#requires -module ExchangeOnlineManagement
$runAsConnection = Get-AutomationConnection -Name 'AzureRunAsConnection'
$ConnectParams = @{
    #We don't have an easy way to retrieve this, and it doesn't take the tenant ID. You have to manually specify it for now
    Organization = 'myorganization.com'
    AppId = $runAsConnection.ApplicationId
    CertificateThumbprint = $runAsConnection.CertificateThumbprint
    ShowBanner = $false
}
Connect-ExchangeOnline @ConnectParams

SET A REMINDER TO RENEW YOUR CERT

The automation runas account certificate expires by default in a year. The good news is that it automatically syncs it with the service account, so you just need to click the renew certificate button and everything else will be taken care of.

image

@JBines

This comment has been minimized.

Copy link

@JBines JBines commented Aug 13, 2020

Thanks for the info! Wondering if you have done any testing around using the cred manager in azure automation?

https://docs.microsoft.com/en-us/azure/automation/shared-resources/certificates

@JustinGrote

This comment has been minimized.

Copy link
Owner Author

@JustinGrote JustinGrote commented Aug 13, 2020

@JBines If you mean windows credential manager, it's not a good choice because the instances are ephemeral. You can keep certificates in either the Azure Automation secrets, or keep them in Azure Key Vault and use the automation key vault integration.

@JBines

This comment has been minimized.

Copy link

@JBines JBines commented Aug 13, 2020

Yep that's what I was thinking to store it as a secure asset in azure automation but I was hoping I could call the cert by using the Get-AzAutomationCertificate instead but I'm guessing that's not going to make it to the certificatestore. It would be nice to have a longer life cert or maybe we can just automate the cert update on the app.

@JustinGrote

This comment has been minimized.

Copy link
Owner Author

@JustinGrote JustinGrote commented Aug 13, 2020

If you're referring to the RunAs cert, Azure Automation handles all of the renewal by just clicking the renew cert button, you don't have to do all of this setup again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment