How to Use App-Only Authentication with Exchange PowerShell

exchange powershell access

As we continue our journey learning about PowerShell and application access, it is helpful to include Exchange PowerShell. There are times when we may want to include actions related to Exchange Online in our scripting. Often, much of that cannot be done via MS Graph. So we look to App-Only access for Exchange PowerShell to fill those gaps. Plus, you may already have Exchange Online scripts that you don’t want to re-write. App-Only access to Exchange Online can allow us to have Exchange Online PowerShell actions be automated, and occur without our interaction.

In our last post we talked about automating Azure AD PowerShell actions using the MS Graph PowerShell SDK. Now, we will look as some Exchange Online tasks as well. So this post will look at how to configure App-Only access for Exchange PowerShell so we can find other processes to automate in the future.


Please understand that the content herein is for informational purposes only. This existence and contents shall not create an obligation, liability or suggest a consultancy relationship. In further, such shall be considered as is without any express or implied warranties including, but not limited to express and implied warranties of merchantability, fitness for a particular purpose and non-infringement. There is no commitment about the content within the services that the specific functions of the services or its reliability, applicability or ability to meet your needs, whether unique or standard. Please be sure to test this process fully before deploying in ANY production capacity, and ensure you understand that you are doing so at your own risk.

Table of Contents

Considerations and Prerequisites
Configure App Registration for App-Only Access to Exchange PowerShell

Considerations and Prerequisites


  • Security First!!! App registrations and the permissions we grant them should be treated like privileged accounts. They should be protected and should have the minimum number of permissions necessary to do the job. Think about it this way, you wouldn’t just hand out the ability to edit User Accounts, right? App registrations have the potential to be abused if they are not managed correctly. Always keep this in mind when you are creating these things.
  • Everything we are talking about here should be tested thoroughly in a test environment. “Testing” with live employees is a great way to mess a lot of things up, and it shouldn’t be done. Sign up for a Dev environment with Microsoft, or create your own Azure AD tenant and test this with a trial license.
  • Since this is an app registration for PowerShell, you COULD potentially use an existing app registration and just add new permissions. However, it is best to limit the number of permissions you are granting to any specific applications and determine on a case by case basic when it makes sense to reuse an existing one versus creating a new one.


  • The account used to create the App Registration must be in one of these Azure AD roles:
    • Application Administrator
    • Application Developer
    • Cloud Application Administrator

Configure App Registration for App-Only Access to Exchange PowerShell

Similar to how we created an app registration for using the MS Graph PowerShell SDK, we will need to create an app registration to allow for app-only Exchange Online PowerShell access. I recommend creating a new one separate from any that you have already. This will make sure you have the correct permissions and to minimize the permissions you are granting this specific application. You can do what makes sense for you, but we will be creating a new one here.

  1. First, navigate to Sign in, and search for App Registrations. Open this up, and create a new registration. Give it a name, and Hit Register.
new exchange powershell app registration page
  1. First we will need to modify the Manifest file to add an API permission. This is easiest when you do it before adding other permissions.
  2. Then, under the Management Section, choose Manifest. On the page that opens, find the requiredResourceAccess entry (on or about line 47) and Modify the resourceAppId, resourceAccess, id to match the JSON code listed below.
"requiredResourceAccess": [
      "resourceAppId": "00000002-0000-0ff1-ce00-000000000000",
      "resourceAccess": [
            "id": "dc50a0fb-09a3-484d-be87-e023b12c6440",
            "type": "Role"

Here is what the manifest will look like. (I recommend just copy and pasting the values over the existing values instead of the entire thing.)

Modify the manifest file to add new API permissions
  1. Next, save the Manifest file, and then go to API permissions tab. You should see Exchange.ManageAsApp is now listed as a new permission. This will allow for your Exchange PowerShell commands to be run as an application.
  1. Finally, to finish our permissions, hit the ‘Grant admin consent for…’ button to grant admin consent. This will enable this application to access Exchange PowerShell.

Creating a Self-Signed Certificate

  1. Next we will create a self signed certificate. Here is a simple code snippet to create your own. Change the CN to match something you will recognize.
$cert = New-SelfSignedCertificate -Subject "CN=Exchange Online App-Only Access" -CertStoreLocation `
  "Cert:\CurrentUser\My" -KeyExportPolicy Exportable -KeySpec Signature -KeyLength 2048 `
  -KeyAlgorithm RSA -HashAlgorithm SHA256
Export-Certificate -Cert $cert -FilePath "C:\Temp\PowerShellAppOnly.cer"
  1. Then back in the Azure Portal, navigate to the Certificates & Secrets section of our App Registration. Choose the Certificates tab, and upload the certificate we just created. You should now see it listed in the Certificates section.
certificate uploaded to the application for authentication
  1. Next our script will need the certificate thumbprint. You can get the thumbprint from the manifest. It will be labeled “customKeyIdentifier“.
  2. Finally, copy the thumbprint to a variable to start off our PowerShell script. Also while you are at it, grab the Application (ClientID) from the Overview page and add that to our script as well.
thumbprint and client ID
First two piece of our PowerShell pie

Azure AD Role Permissions

So with at this point, our last step is to assign our application an Azure AD role. Exchange PowerShell is still an authenticated process, even if it isn’t a person performing the steps.

  1. First, open Azure Active Directory, and navitgate to Roles and administrators. Once there search for Exchange Administrator, and click the role to open the assignments page.
Roles and administrator tab in Azure Active Directory
  1. Next, click on Add assignments at the top, and search for the application we just created. You should see the application listed with the Type of ‘ServicePrincipal‘.
Assigning Exchange Administrator permissions to our application

Finally, this finishes off the permissions section for this application. All that is left is to finalize our script and we are ready to test.

Finish and Test our Sample Script

  1. To finish our script so we can get connected, we need to grab our Primary Domain and save that to a variable as well. Go back to Azure Active Directory home page. There you should see the Primary Tenant listed. Copy this and save it as a variable that we can call to get connected.
  2. Next add this line to our script as our connection string. This will use the information we have collected to get us connected.
Connect-ExchangeOnline -CertificateThumbPrint $thumb -AppID $client -Organization $org

It should look like this once it is all put together.

final connection details to run our application

Now it is time to test our application. Run your script and make sure you get connected. Once you are connected, run a few sample commands and see what comes back. Try the one listed below:

Get-EXOMailbox | Select  Name,PrimarySmtpAddress,Guid

In my Dev tenant, this returns the following examples:

As long as your are getting results, you are good to go! Congrats! You have successfully connected to Exchange Online PowerShell with application only access.


There you have it! Now you can start to automate your Exchange Online scripts. You may be thinking, ya know this is kind of cool but what would I need it for. There may or may not be scenarios where you want to have this run as unattended access instead of manually connecting. That will vary between people and organizations.

In my next post, I plan to break down one example that I have used this for regarding former employee mailboxes. With that we will combine it with MS Graph and send email notifications as well as gather information. Seeing the power of MS Graph and Exchange Online PowerShell together might give you some ideas that you can use for practical application. If not, then just stick around and maybe eventually I’ll find something useful for you.

I’m always open to feedback, and look forward to hearing what you think about this post. As always, hit me up on Twitter @SeeSmittyIT to let me know what you thought of this post. Thanks for reading!


Curtis Smith works in IT with a primary focus on Mobile Device Management, M365 Apps, and Azure AD. He has certifications from CompTIA and Microsoft, and writes as a hobby.

View all posts by Smitty →