6 min read
Boost your IT automation efficiency with new ScriptRunner release
We have just released our latest ScriptRunner update, version 7.1, packed with powerful new features aimed at making IT...
ScriptRunner Blog
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.
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]
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)
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.
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:
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':
(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.
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:
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:
API Permissions in Azure registered Apps.
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:
$NewCertificate = New-SelfSignedCertificate -DnsName "PowerShellGeek.com" -CertStoreLocation "cert:\CurrentUser\My" -NotAfter (Get-Date).AddYears(1) -KeySpec KeyExchange
$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?
$NewCertificate | Export-Certificate -FilePath c:\ExOConnection.cer
Note that the username for the above credential prompt is not used but we have to enter something to capture at least the password.
Two files created with PowerShell for use later in the process.
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.
Certificates for Azure app
Click on 'Upload certificate' and select the certificate that was created with PowerShell:
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.
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.
Click on Add assignments, search for the app that was created, select and click 'Add' to grant this user permissions.
Adding an assignment for an Azure AD role group
Once we have a cert, API permissions and cert associated with the app, we can now use ExO PS v3 to connect.
Install-Module ExchangeOnlineManagement
Import-Module ExchangeOnlineManagement
In order to make a proper connect with PowerShell using CBA, we need a few components:
As mentioned and documented earlier, we need the Thumbprint of the certificate we created and associated with the Azure app:
AE20B242AE58AA3ABED4D57C22253E2F7572B404
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
Now we are connected to Exchange Online with a certificate
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.
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.
(Left) one Azure app mapped to multiple workloads
(Right) one Azure app mapped to one workload only
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!
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.
Sep 30, 2024 by Frank Kresse
We have just released our latest ScriptRunner update, version 7.1, packed with powerful new features aimed at making IT...
Aug 16, 2024 by Heiko Brenn
Welcome to Scriptember! We are thrilled to announce the launch of a unique, month-long campaign dedicated to...
Aug 14, 2024 by Jeffery Hicks
I'd like to think that because you are reading this, you are a professional PowerShell user and this article will be a...
Damian Scoles is a ten-time Microsoft MVP specializing in Exchange, Office 365 and PowerShell who has 25 years of IT industry experience. He is based in the Chicago area and started out managing Exchange 5.5 and Windows NT. Over the years he has worked with Office 365 since BPOS and his experience has grown to include Azure AD, Security and Compliance Admin Centers, and Exchange Online. His community outreach includes contributing to TechNet forums, creating PowerShell scripts that can be found on his blogs, writing in-depth PowerShell / Office365 / Exchange blog articles, tweeting, and creating PowerShell videos on YouTube. He has written five PowerShell books and is also actively working on the book "Microsoft 365 Security for IT Pros".