Configure Exchange Online Certificate Based Authentication for unattended scripts

Table of Contents


How to schedule an Exchange Online PowerShell script for automation purposes? For example, you have an Exchange Online PowerShell script that needs to run daily against the Exchange Online tenant unattended without any interaction. In this article, you will learn how to configure Exchange Online Certificate Based Authentication (CBA) and automate Exchange Online PowerShell scripts. You must NOT use username and password for this connection anymore, as is was not secure for this today.

Certificate Based Authentication

Running scripts in Microsoft 365 often involves unattended scripts in Exchange Online PowerShell. In the past, unattended sign-in required you to store the username and password in a local file or in a secret vault that’s accessed at run-time. But, as we all know, storing user credentials locally is not a good security practice.
That’s where Certificate Based Authentication (CBA) comes to the rescue. It supports unattended script and automation scenarios using Azure AD apps and self-signed certificates. This eliminates usernames, passwords, and MFA when authenticating - yes, thats nice!

How Certificate Based Authentication works

The Exchange Online PowerShell module uses the Active Directory Authentication Library to fetch an app-only token using the application Id, tenant Id (organization), and certificate thumbprint. The application object provisioned inside Azure AD has a Directory Role assigned to it, which is returned in the access token. The session’s role based access control (RBAC) is configured using the directory role information that’s available in the token.

How to set up Certificate Based Authentication in Exchange Online

Let’s go through the below steps and set up Exchange Online Certificate Based Authentication for unattended scripts.

1. Generate self-signed certificate

To generate a self-signed certificate, log onto any Windows Server or Desktop with Windows PowerShell. It’s best to generate the certificate on the machine you want to run the unattended PowerShell script.
You need the self-signed certificate later in the steps when you upload it to the application in Azure and if you want to use the certificate on other systems.

Note:
By default, self-signed certificates are valid for one year.

In this case, we added 5 years to the self-signed certificate, so we don’t have to renew it yearly.

PS C:\> $mycert = New-SelfSignedCertificate -DnsName "domain.com" -CertStoreLocation "cert:\LocalMachine\My" -NotAfter (Get-Date).AddYears(5) -KeySpec KeyExchange -FriendlyName "EXO unattended cert"

Confirm the certificate and copy the ThumbPrint and paste it into Notepad. You will need it later when connecting to Exchange Online.

PS C:\> $mycert | Select-Object -Property Subject,Thumbprint,NotBefore,NotAfter
Subject      Thumbprint                               NotBefore             NotAfter
-------      ----------                               ---------             --------
CN=domain.com 4F3CB0EFE918A3544274F9E2D54AB1BEE8B96B78 1/2/2023 6:45:21 PM 1/2/2028 6:45:22 PM
Export certificate to .cer file.

PS C:\> $mycert | Export-Certificate -FilePath "C:\temp\EXOUnattendedCert.cer"
    Directory: C:\temp
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       1/2/2023   6:46 PM            796 EXOUnattendedCert.cer
Export certificate to .pfx file.

PS C:\> $mycert | Export-PfxCertificate -FilePath "C:\temp\EXOUnattendedCert.pfx" -Password $(ConvertTo-SecureString -String "P@ssw0Rd1234" -AsPlainText -Force)
    Directory: C:\temp
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       1/2/2023   6:48 PM           2725 EXOUnattendedCert.pfx

2. Register application in Azure

To register an application in Azure AD, follow these steps:
  • Sign in to Microsoft Azure
  • Click on Menu > Azure Active Directory
  • Select App registration > New registration


  • Fill in the name EXO PowerShell unattended
  • Keep the default supported account types Accounts in this organizational directory only – (Single tenant)
  • Click Register


  • The EXO PowerShell unattended application Overview appears
  • Copy the Application (client ID) and paste it into Notepad because you will need it later when connecting to Exchange Online



3. Configure Azure application API permissions

You need to add API permissions to the EXO PowerShell unattended application you created, by following the below steps:

  • Click on API permissions > Add a permission


  • Click APIs my organization uses
  • Search for Office 365
  • Select Office 365 Exchange Online from the results list


  • Select Application permissions
  • Expand Exchange and select Exchange.ManageAsApp
  • Click Add permissions

  • Click on Grant admin consent
  • Click Yes


  • The status shows a green checkmark




4. Upload certificate to application

It’s time to upload the self-signed certificate you created in the previous step:

  • Click on Certificates & secrets
  • Click Certificate > Upload certificate


  • Click on the browse icon and select the self-signed EXOUnattatended.cer file in C:\temp
  • Add the description EXO Unattended Cert
  • Click Add
  • The certificate appears in the list

Note: Confirm that it has the same certificate thumbprint as the one you exported in the previous step.


5. Assign application to Exchange administrator role

The last step is to add the application as a member to the Exchange Administrator role:

  • Click on Menu > Azure Active Directory
  • Select Roles and administrators
  • Select All roles and search for exchange
  • Click on Exchange Administrator


  • Click on Assignments > Add assignments > Active assignments


  • Click No member selected
  • Search for the Azure application name EXO PowerShell unattended
  • Select the application from the results
  • Click Select


  • Select Setting
  • Enter something regarding this in the justification field
  • Click Assign


  • The EXO PowerShell unattended application is added to the Exchange Administrator role assignments list


All the steps are completed.

Connect to Exchange Online PowerShell with Certificate Based Authentication

Let’s look at connecting to EXO PowerShell with CBA (Certificate Based Authentication).

It’s essential to Install Exchange Online PowerShell module on the machine. If you don’t have it installed, it’s impossible to connect.

Fill in the below three variables to connect to Exchange Online PowerShell with Certificate Based Authentication:

  1. $AppId
  2. $CertificateThumbPrint
  3. $Organization
$AppId = "cd4fad71-3820-4198-8748-b88035aeec51"
$CertificateThumbprint = "4F3CB0EFE918A3544274F9E2D54AB1BEE8B96B78"
$Organization = "domain.onmicrosoft.com"
Connect-ExchangeOnline -AppId $AppId -CertificateThumbprint $CertificateThumbprint -Organization $Organization -ShowBanner:$false

Now that you have a connection to Exchange Online PowerShell, run the Get-EXOMailbox cmdlet to retrieve the mailboxes.

PS C:\> Get-EXOMailbox -ResultSize 5 | ft Name,UserPrincipalName
Name          UserPrincipalName
----          -----------------
Amanda Morgan Amanda.Morgan@domain.com
Amelia Nash   Amelia.Nash@domain.com
Carol Baker   Carol.Baker@domain.com
Craig Hansen  Craig.Hansen@domain.com
Curt Berry    Curt.Berry@domain.com

Unattended PowerShell script example

Note: Add Disconnect-ExchangeOnline -Confirm:$false at the end of the PowerShell script. If the script runs without disconnecting the session, you could use up all the remote PowerShell sessions available, and you’ll need to wait for the sessions to expire.

#Connect Exchange Online PowerShell
$AppId = "cd4fad71-3820-4198-8748-b88035aeec51"
$CertificateThumbprint = "4F3CB0EFE918A3544274F9E2D54AB1BEE8B96B78"
$Organization = "domain.onmicrosoft.com"
Connect-ExchangeOnline -AppId $AppId -CertificateThumbprint $CertificateThumbprint -Organization $Organization -ShowBanner:$false
# Split path
$Path = Split-Path -Parent "C:\temp\*.*"
# Create variable for the date stamp
$LogDate = Get-Date -f yyyyMMddhhmm
# Define CSV and log file location variables
$Csvfile = $Path + "\AllMailboxes_$logDate.csv"
Get-EXOMailbox -ResultSize Unlimited | Select-Object DisplayName, PrimarySmtpAddress | Sort-Object PrimarySmtpAddress | Export-CSV -Path $Csvfile -NoTypeInformation -Encoding UTF8
# Disconnect Exchange Online PowerShell
Disconnect-ExchangeOnline -Confirm:$false

This is how it looks when opening the CSV file with Notepad.

xxx

That’s it!

You did successfully set up Exchange Online Certificate Based Authentication in Exchange Online.

Full PowerShell:

Conclusion

You learned how to configure Exchange Online Certificate Based Authentication for unattended scripts. Go through the step-by-step guide, and you can authenticate with Exchange Online PowerShell without user interaction. Remember to back up the self-signed certificate so you can import and use it on other machines.

Previous Post Next Post