The 1-2-3 of Exchange Online Certificate Based Authentication for PowerShell

Basic Authentication for PowerShell to Disappear in 2021

The writing team for Office 365 for IT Pros very much appreciate the work done by our redoubtable technical editor, Vasil Michev, when he probes and questions text in the book chapters. It’s nice to get some of our own back when Vasil commits himself to print.

Take his recent article on certificate-based authentication for Exchange Online PowerShell. There’s a lot of good stuff here, but Vasil’s mind runs at such a fast rate that he sometimes omits details when he explains something that end up stopping people being able to master a topic. This is when people with slower CPUs, like me, step in to ask irritating questions. In this instance, the topic is important. Microsoft will remove support for basic authentication for PowerShell in mid-2021. Any batch job that uses PowerShell to interact with Exchange Online needs to be upgraded before this point to keep working.

Three Steps to Certificate-Based Authentication

The solution is to move to the Exchange Online Management module (known as EXO V2) and use certificate-based authentication. Microsoft has a preview of the module available to allow tenants to test how this works. The mechanism might seem complex when you first read Microsoft’s instructions, but it can be boiled down to three points:

  • An app registered with Azure AD. The app is the entry point to Exchange Online PowerShell because it is granted permission (as a service principal) to perform administrative actions. You might have used apps registered with Azure AD to interact with the Microsoft Graph.
  • A self-signed X.509 certificate used to authenticate the application against Azure AD when access is needed.
  • Office 365 is a massive multi-tenant environment, so you need to tell Exchange Online which tenant to connect to be able to run PowerShell in a background process.

Creating the App and Assigning Permissions and Role

Creating the app and assigning the necessary Exchange.AsManageApp permission and administrative role is quickly done in the Azure AD portal using the steps outlined in Vasil’s article. These are one-time operations that don’t need to be automated in code. However, it’s worth noting that role assignments can be made with PowerShell. It’s useful to know how to do this because you might use the technique in future to assign a role to a user.

This code fetches the object identifier for the app (it’s called “Exo Background process”) and assigns the Exchange Service Administrator directory role to the app.

The same approach is used to assign a role to a user. The difference is that the object identifier for the user is fetched with the Get-AzureUserAD cmdlet. This example shows how to assign the Global Reader role to a user.

With that diversion taken care of, we can proceed to obtaining a self-signed X.509 certificate, which is where people sometimes become stuck (I did).

Creating the Certificate

You need to upload a suitable X.509 self-signed certificate to the Azure AD app to create an association between the two. Certificates are not the easiest of objects to work with, but in this case it’s straightforward.

If you don’t have a suitable certificate to hand, you must generate one. Vasil was short on detail on this point (until I asked him how he had generated a certificate). Microsoft recommends using either the Create-SelfSignedCertificate.ps1 script or the MakeCert command-line utility. These are certainly viable options, but the easiest way is to run the New-SelfSignedCertificate cmdlet using a command like this:

This command creates a certificate valid for a year in the personal store of the user, which is fine for testing (Figure 1). Obviously, in a production environment, you’d create the certificate in the personal store of the account that will be used to run batch jobs.

 self-signed certificate created with the New-SelfSignedCertificate cmdlet
Figure 1: A self-signed certificate created with the New-SelfSignedCertificate cmdlet

To associate the certificate with the app, export the certificate as a DER-encoded binary X.509 file (Figure 2). You can call the file anything you like, but you should give it a .CER extension.

Exporting the self-signed certificate
Figure 2: Exporting the self-signed certificate

Finally, upload the exported file to the app in the Azure AD portal. This will generate a thumbprint that you need to note (Figure 3).

Importing the self-signed certificate into the registered Azure AD app
Figure 3: Importing the self-signed certificate into the registered Azure AD app

Bringing it Together

After setting up the app, the three vital pieces of information we need to connect are:

  • The AppId of the application you created.
  • The thumbprint of the certificate loaded into the app.
  • 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:

There are obviously more complications that await the unwary along the way, but this is enough to connect and play with Exchange Online PowerShell in batch jobs. Vasil’s post contains a lot of detail and there will be more articles and guidance published as we approach the deadline for basic authentication to disappear next year, which is a good reason to subscribe to a reliable source of information like the Office 365 for IT Pros eBook.

One Reply to “The 1-2-3 of Exchange Online Certificate Based Authentication for PowerShell”

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.