Skip to the main content.

ScriptRunner Blog

How to connect to Exchange Online with certificate based authentication (CBA)

Table of contents

 

 

Post Featured Image

Learn more about Certificate Based Authentication for Exchange Online PowerShell now that Basic Authentication has been disabled. 

PowerShell and Security are not 'two ships passing in the night' but should be intertwined in the minds of administrators who execute their scripts on-premises or in the cloud. Connecting and working with Exchange Online via PowerShell is no different. In this article we will explore some changes that administrators will have to make in order to connect with PowerShell now that Basic Authentication has been disabled. We will review the various connections, security that goes with that and then finally cover Certificate Based Authentication for Exchange Online PowerShell.

 

Credential store options

This first line of defense when connecting to a target system is how to pass credentials to that system. With PowerShell, we have many options and administrators have probably used at least three or more of the below methodologies when working with the systems they support:

Clear Text: in the script [bad, do not do this] – example: Uber Hack
Password File: Encrypted file on local machine [Slightly better than clear text, bad if file permissions are not set]
Local Credentials: PowerShell Secrets module [more secure than a password file, encrypted]
Certificates: Use a self-signed or third-party certificate for proof of identity (Azure App registration required) [most secure]
Azure Automation Credentials: Requires some configuration in Azure [most secure]
Azure Key Vault: Credentials are stored in an Azure Key Vault (requires Azure resources) [most secure]

 

Changing authentication

Up until October 1, 2022, administrators were able to connect to Exchange Online with Basic Authentication using the New-PSSession cmdlet (along with a few other criteria). Now that Microsoft has shut that door and is no longer allowing for those connections, we need to consider other options. Then on December 15, Microsoft again announced another change for Exchange Online PowerShell connections where RPS (Remote PowerShell) is also blocked (as of July of 2023 – Microsoft Announcement and Update)

 

What does this change eliminate?

  • Any connection made with New-PSSession
  • Exchange Online PowerShell module v1 or v2
  • Any Exchange Online PowerShell module using the -UseRPSSession parameter

 

What is the substitute?

All is not lost as Microsoft has provided a method of connect to Exchange Online using PowerShell. These include using the Exchange Online PowerShell module v3 (no -UseRPSSession parameter) or using Certificate Based Authentication (CBA). In this article, we will explore the use of CBA as this can be used for interactively running scripts as well as securely running automation scripts for performing tasks with no user intervention.

 

How to set up CBA

Setting up Certificate Based Authentication for Exchange Online requires just a few components. We need to meet a few prerequisites to make a successful connection with PowerShell:

  • 1. Register an application in Azure AD
  • 2. Assign API permissions to the app
  • 3. Create Self-Signed Certificate
  • 4. Associate Certificate with Azure App
  • 5. Assign Azure AD roles

 

Register application

First, browse directly to the App Registrations page in your Azure tenant:
https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade

Once here, click on the 'New Registration button':

01_register an application

(1) Add a name for the app, (2) Leave the default account types (most scenarios), (3) Select Web from the drop down, (4) Enter a domain for this redirect. Click Register and we have an app to use with PowerShell.

 

Assign API permissions to the app

This part is a bit trickier, but Microsoft provides good instructions here in their documentation. The steps boil down to this:

1. Click on the app you just created in your tenant, make the modifications documented in this step per Microsoft on the applications Manifest code:

02_JSON needed for access

JSON needed for access (per Microsoft documentation)

 

2. Then go to 'API permissions' for the app and (1) Grant consent and (2) add this Exchange permission:

03_API permissions in Azure

API Permissions in Azure registered Apps.

 

Create a self-signed certificate

Next, we need the certificate that will be used to validate the connection between the console running the PowerShell script and Exchange Online. We can generate a self-signed certificate using PowerShell. For example, an organization with a domain of PowerShellGeek.com need to create the certificate, which is important we will need this for the app and the certificate:

 

Generate the certificate


$NewCertificate = New-SelfSignedCertificate -DnsName "PowerShellGeek.com" -CertStoreLocation "cert:\CurrentUser\My" -NotAfter (Get-Date).AddYears(1) -KeySpec KeyExchange

 

Generate a PFX version of the certificate


$NewCertificate | Export-PfxCertificate -FilePath ExOConnection.pfx -Password (Get-Credential).password

Note: Markus from the ScriptRunner team also talked about this in the blog post How do I create PFX files with PowerShell?

 

Generate a CER version of the certificate


$NewCertificate | Export-Certificate -FilePath c:\ExOConnection.cer 

04_credential request

Note that the username for the above credential prompt is not used but we have to enter something to capture at least the password.

05_a files created with PowerShell

05_b files created with PowerShell

Two files created with PowerShell for use later in the process. 

Add certificate to Azure app

Now that we have a certificate, we can add this to our Azure App we created previously. Browse back to the Azure Portal,  then to 'App Registrations':

Find the app you created in the previous step and open it up. Then click on Certificates & Secrets.

06_certificates for Azure app

Certificates for Azure app

Click on 'Upload certificate' and select the certificate that was created with PowerShell:

07_ExO PowerShell Access

Make sure to get the thumbprint of the certificate at some point during this process as it will be needed for connecting to Exchange Online PS. For this example, the certificate thumbprint is: AE20B242AE58AA3ABED4D57C22253E2F7572B404

Note: Make sure to secure the generated certificate files with appropriate NTFS permissions to ensure that it does not become the weakest link in your secure PowerShell communications. 

 

Assign Azure AD roles

The last part of the process is now granting access to this Azure app for various roles in Azure AD which will allow a user with these roles assigned to connect with PowerShell with the correct permissions. This is done in the Azure AD Portal (https://aad.portal.azure.com). For this example, we will assign the role to 'Global Administrators', but could just as easily assign it to the 'Exchange Services Admin' role.

08_add assignments

Click on Add assignments, search for the app that was created, select and click 'Add' to grant this user permissions.

 

09_add assignments

Adding an assignment for an Azure AD role group

 

How to connect with CBA

Once we have a cert, API permissions and cert associated with the app, we can now use ExO PS v3 to connect.

Download PowerShell for ExO v3


Install-Module ExchangeOnlineManagement

Load module in PowerShell


Import-Module ExchangeOnlineManagement

Connecting to Exchange Online PowerShell

In order to make a proper connect with PowerShell using CBA, we need a few components:

(A) Thumbprint from the certificate process:

As mentioned and documented earlier, we need the Thumbprint of the certificate we created and associated with the Azure app:

AE20B242AE58AA3ABED4D57C22253E2F7572B404

(B) We also need the application ID of the Azure app that was created:

10_ExO PowerShell  Access

Where to find the Azure App ID for PowerShell

Once we have those two, we can now connect to Exchange Online with the certificate:


Connect-ExchangeOnline -CertificateThumbPrint <Certificate Thumbprint> -AppID <App ID> -Organization "<tenant>.onmicrosoft.com"

 


Connect-ExchangeOnline -CertificateThumbPrint AE20B242AE58AA3ABED4D57C22253E2F7572B404 -AppID 279fcdda-c0b9-4f99-b2d7-c99dd2376d3c -Organization tenantdomain.onmicrosoft.com

11_Exchange Online connected with a certificate

Now we are connected to Exchange Online with a certificate

 

Why use CBA?

Now that we know how to set this up and how to use it, why bother to use CBA? The ExO v3 module can connect to Exchange Online without CBA. We can feed credentials from a secure text file, the Secrets PowerShell module or manually enter credentials. Why use CBA at all? CBA provides a more secure connection, does not leave vulnerable your login credentials (login name and password) and is considered more secure to use. CBA also streamlines your authentication and makes script automation easier.

Which other workloads can use CBA?

  • Security and Compliance Center PowerShell
  • Microsoft Teams
  • SharePoint PNP
  • etc.

Each of these workloads should have a separate app so that they can be assigned by least privilege. Otherwise, if all access is provided via one app, then a user assigned that app may have greater permissions than they need to perform their job thus creating a security problem. 

12_mapping

(Left) one Azure app mapped to multiple workloads
(Right) one Azure app mapped to one workload only

 

Conclusion

Certificate based authentication is just one method of authentication for Exchange Online, but it provides a more secure connection than the ones involving administrators login and password (clear text, secure file or otherwise). Switching to CBA for Exchange Online is something administrators should be doing as setup is easy, convenient, secure and it can be used in automated scripts as well as other workloads like Security and Compliance Center, SharePoint PnP and Teams.

Do not be hacked like Uber was with clear text passwords in your script files!

 

Good2know

Webinar: PowerShell security best practices

Running PowerShell scripts securely is essential when it comes to administration of complex IT infrastructures. Amongst others, the necessary credentials have to be kept safe. 

PowerShell itself already comes with a lot of security features, and ScriptRunner extends these for secure delegation and central management of scripts and credentials.

This webinar is aimed at administrators, IT and DevOps professionals, PowerShell developers and IT managers.

 

powershell-security

 

This webinar is about:

  • How to use the PowerShell SecretManagement module
  • Working with execution policies
  • Secure credential management
  • Password server integration
  • Delegation of single, parameterizable PowerShell scripts without administrative rights of the user
  • Secure browser-based execution of PowerShell scripts

 

 

Click here for the recording

 

 

 

Related links 

Related posts

About the author: