Use PowerShell to Connect to Exchange Online unattended in a Scheduled Task

If you have MFA enabled, how do you connect to Exchange Online in an unattended script, like a Scheduled Task? Some people may have embedded a password into their scripts, but that will stop working in mid 2021 when Microsoft retires basic authentication in Office 365.

Microsoft has a preview version of Exchange Online v2 PowerShell that allows you to use a Certificate to authenticate.

Why Certificates? Because you don’t want an MFA push notification on your iPhone every morning at 1:00 AM, right?

Recommendation: Review to see if you have any automated scripts connecting to Exchange Online (typically scheduled tasks).

How? Follow the steps below to use certificates to connect to Exchange Online PowerShell

Prerequisites

Install-Module ExchangeOnlineManagement -RequiredVersion 2.0.3-Preview

Or if you already have a previous version of the module installed:

Update-Module ExchangeOnlineManagement -RequiredVersion 2.0.3-Preview

Note: If you get an error “A parameter cannot be found that matches parameter name ‘AllowPrerelease’” then run this command
Install-Module PowershellGet -Force (then close and re-open PowerShell)

Instructions

  1. Register an app in Azure AD (here).
    (The app is the entry point to Exchange Online PowerShell because it creates a service account called a service principal to perform administrative actions)
    image
  2. Click API Permissions on left navigation > Add a permission
    image
  3. Scroll to the bottom of the Request API permissions pane and click on Exchange under the Supported legacy APIs section.
    image
  4. Click on Application permissions
    image

  5. Expand the Exchange entry, and select the Exchange.ManageAsApp permission.
    Click the
    Add permissions button below to complete the operation.
    image
  6. Click “Grant Admin consent for your tenant”
    image
  7. Create a Role to assign to the App (Thanks to Tony Redmond for this tip)

$ExoAppSp = (Get-AzureADServicePrincipal -Filter “DisplayName eq ‘Exchange Online Scripting'”).ObjectId

$ExoRoleId = (Get-AzureADDirectoryRole | ? {$_.DisplayName -eq “Exchange Service Administrator”}).ObjectId

Add-AzureADDirectoryRoleMember -ObjectId $ExoRoleId -RefObjectId $ExoAppSp

  1. Create a self-signed X.509 certificate that will be used for authentication
    New-SelfSignedCertificate -Subject “Exo Background Process” -CertStoreLocation “cert:\CurrentUser\My” -KeySpec KeyExchange -FriendlyName “For EXO V2 Background Jobs”
  2. Open MMC, add Certificates, Find the new Cert, and Export it *without* the private key, as a .CER file.
    image
  3. Upload this file to the app you registered in the Azure Portal
    image

After adding the certificate, we need three items before we can finally connect unattended with PowerShell

  • The AppId of the application you created.
    Get-AzureADApplication -Filter “DisplayName eq ‘Exchange Online Scripting'”
  • The thumbprint of the certificate loaded into the app
    Get-ChildItem -path ‘Cert:\*’ -Recurse |where {$_.Subject -like ‘*EXO*’}
  • The service domain for your tenant (like tenant.onmicrosoft.com).

With these values, you can connect to Exchange Online using certificate-based authentication with a command like:
Connect-ExchangeOnline -CertificateThumbprint ” 960BD967A9287CE83DF4138805B5CE2FCA4C9B8B” -AppId “b83c46c6-044e-40e5-929c-634f80045a11” -ShowBanner:$false -Organization tenant.onmicrosoft.com

To connect to Azure AD with a certificate see:

Using a service principal | Microsoft Docs

References

· Microsoft Documentation

· Vasil Michev

· Tony Redmond: Office 365 IT Pros