The same question as been asked for a long time: How can EXO recipient management be done without the need of administrative accounts?
Microsoft Graph does not cover the entire recipient management in Exchange Online and Microsoft customers have been asking for a solution for a long time.
Now as Microsoft turns off Basic authentication, it looks like there is some movement.
“Some movement?” Microsoft has put a lot of efforts into this in order to make Modern Authentication available in all ways. Here are some good articles, which explain the basic principals of modern authentication and the deprecation of basic authentication:
With the new Exchange Online PowerShell v2 module, not only is performance addressed, there are additional methods of authentication which open up new scenarios:
Modern Authentication is now natively available in the module, which unlocks several OAuth2 flows. Here's more information on OAuth 2.0 and OpenID Connect protocols on the Microsoft identity platform.
What does this have to do with EXO automation?
The Product Group introduced the so-called client credentials grant flow. With this flow you can acquire an access token non-interactively with either a “client secret”, which is basically a string like password, or a certificate.
As of now only certificate for authentication is implemented and can be used with the following restrictions:- If the parameter CertificateThumbprint is used, only the CurrentUser certificate store is searched for the certificate
- Combination of CertificateFilePath and CertificatePassword consumes a PFX file and its corresponding password
Setup made easy
Now that we have the ability to use certificates in our authentication flow, we can use this mechanism in scenarios like scheduled tasks and eliminated the need of service accounts.
The required steps to leverage this are outlined in this article on App-only authentication for unattended scripts in the EXO V2 module. Here is a short summary:- A certificate (could be a self-signed or an existing one from your PKI)
- A registered application in Azure AD with ManageAsApp assigned Application permissions and a assigned supported RBAC role
The list doesn't seem too long, but there's still a few steps and it will take some time. In order to reduce the time you can use Dave’s PowerShell module PowerShell module PSServicePrincipal. With this module it’s super easy to perform all required configuration steps within seconds:
The only thing that needs to be done is granting admin consent for your registered application:
All other steps are done by the script:
Create and export a self-signed certificate
Registering an application and add the certificate
Assigning one of the supported roles (Contributor in this case):
If you want, you can do these steps by yourself and in case you need a script for generating a self-signed certificate:
Since a few versions a script “Create-SelfSignedCertificate.ps1” is included and shipped with the module. Just have a look into module’s directory.
At this time, I also want to highlight another post for automation provided by Glen Scales, which includes MFA using TimebasedOneTimePassword TOTP: Using 2 Authentication factors (for MFA) in an unattended PowerShell Script
Outlook for the Future
Even though the current solution is a huge step forward, you cannot use the module for maintaining Exchange Online objects in an automated way in Azure Functions or Power Automate. With this you finally could implement self-service scenarios for your end-users serverless or take action on certain events for a user object and much more.
But the Product Group listened to feedback and as you might have noticed, they are already working to support PowerShell Core:- Microsoft 365 Roadmap
You can already test it with the preview version 2.0.2 of the EXOv2 PowerShell module. It shows “netCore”(PowerShell Core) and “netFramework”(PowerShell):
But most importantly:
The PG committed for adding additional parameter:- One, which will accept a certificate object of type [System.Security.Cryptography.X509Certificates.X509Certificate2]
- Another, which will accept shared secret for client credentials grant flow
Why get excited about this?
If we have a parameter, which accepts a certificate object, you don’t need to have the certificate somewhere installed or saved in a PFX file in the filesystem somewhere. Besides the fact that this reduces potential leakage (everybody with access to the filesystem would be able to get the certificate) this will unleash the usage:
You will be able to store your certificates or client secrets in Azure Key Vault and follow best security practices.
A while ago I wrote my own script Get-AccessToken.ps1 for testing purposes. At the beginning the idea was to test all kind of OAuth2 flows for acquiring access token from Azure AD. You can find the Get-AccessToken script here and some info on OAuth: Get-AccessToken. on my blog.
For the client credential flow I have a parameter Certificate, which accepts object of type [System.Security.Cryptography.X509Certificates.X509Certificate2]. With this certificate I create ClientAssertation and acquire a certificate, which is the same process the new Exchange Online PowerShell v2 performs.
The future could look like this:- Store a certificate or secret in Azure Key Vault
- Retrieve in your solution for automation either certificate or secret
- Use the secret for authentication in the Exchange Online PowerShell v2 module
Here you can see my Azure Key Vault named EXOv2, where I stored a secret and a certificate:
You can use Azure PowerShell either from your local computer or even in the browser. I will show you how to use it in your browser.
Sign-in to Azure Portal and start your Azure Cloud Shell
With Get-AzKeyVaultCertificate you will receive the certificate, but you won’t have the private key. This is by design as a certificate is stored in a key vault in 3 parts:
In order to retrieve the certificate including the private key and therefore to be able to use it for authentication, you need to use Get-AzureKeyVaultSecret:
Yes, you will now blame me that there is no certificate or something with type of [System.Security.Cryptography.X509Certificates.X509Certificate2].
But see what happens when you convert the attribute SecretValueText:
And now let’s store the converted string into a variable:
Now you could use the variable for authentication.
Same procedure for retrieving the secret string:
This was part one of two parts about the series Exchange Online Automation with EXOv2 module. In part two I will cover how you can access Azure Key Vault using REST API. Stay tuned.
Monitor Your Hybrid - Office 365 Environment with ENow
ENow’s Office 365 Monitoring solution is like your own personal outage detector that pertains solely to you environment. ENow’s solution monitors all crucial components including your hybrid servers, the network, and Office 365 from a single pane of glass. Knowing immediately when a problem happens, where the fault lies, and why the issue has occurred, ensures that any outages are detected and solved as quickly as possible. Monitor Your Hybrid - Office 365 Environment with ENow.