PowerShell script to retrieve all Exchange Online users with an on-premise AD account who are not enabled for remote mailbox

Many organizations are and will continue to have a hybrid environment where user accounts are created on an on-premise Active Directory and their mailboxes are created in Exchange Online linked to their Entra ID synchronized account with AD Connect. Those who still maintain an on-premise Exchange hybrid environment will know that whenever an on-premise user is assigned an Office 365 license, which creates their mailbox, they would need to use the Enable-RemoteMailbox PowerShell cmdlet to create a corresponding reference on their on-premise Exchange so it is aware of this O365 mailbox and will be able to route emails to it.

One of the clients I worked in the past asked if there could be a way to schedule a script that will automatically enable any users who do not have a remote mailbox created on their on-premise Exchange and this blog post serves to provide the script and setup.

Step #1 – Create an App Registration used to run Exchange Online cmdlets

We’ll begin by creating an App Registration that is granted the required permissions to run the required Exchange Online cmdlets:

Proceed to grant and consent to the following Application API permissions:

Microsoft Graph:

  • Directory.Read.All
  • Directory.ReadWrite.All
  • User.Read.All
  • User.ReadWrite.All

Office 365 Exchange Online:

  • Exchange.ManageAsApp

Create and upload a certificate for authentication:

Step #2 – Create an on-premise AD service account

We’ll be scheduling a task in Task Scheduler on a server to periodically run this script so we’ll need a service account:

In order to run the required on-premise Exchange PowerShell cmdlet, we’ll need to add the service account to the Recipient Management group:

Next, add the service account to the local administrators group on the server that will be running the PowerShell script:

Step #3 – Place the script on the server that will run it

The PowerShell script I created can be found at my following Github repo: https://github.com/terenceluk/Active-Directory/blob/main/Exchange/Exchange-Remote-Automation.ps1

The script will perform the following:

  1. Authenticate with Connect-MgGraph using certificate authentication (the certificate public/private key is installed in the Local Machine store)
  2. Authenticate with Connect-ExchangeOnline using the same certificate
  3. Retrieve all Exchange Online mailboxes
  4. Retrieve all cloud users (users who are not in the on-premise AD)
  5. Subtract the list of Exchange Online mailboxes with the user who are cloud only (we can’t enable cloud only accounts on the on-premise Exchange)
  6. Connect to the local on-premise Exchange using the service account this script will be ran
  7. Retrieve all the users who are enabled with Remote Mailbox
  8. Take the list of Exchange Online users and remove users who are already enabled with Remote Mailbox
  9. Loop through all the users who need to be enabled for Remote Mailbox and enable them

The script will need the following updated:

  1. Client ID of the app registration
  2. Tenant ID of the teannt
  3. Certificate thumbprint
  4. tenant.mail.onmicrosoft.com domain
  5. FQDN of on-premise Exchange

Step #4 – Create Task Scheduler

With all the core components in place, we can now create the task scheduler to run on a schedule:

Configure the General tab as such:

Configure the desired trigger:

Configure the Action as such:

Program/script: “C:\Program Files\PowerShell\7\pwsh.exe”

Add arguments (optional): -File “C:\Scripts\Exchange-Remote-Automation.ps1”

Start in (optional): C:\Scripts\

That should be it.