Run PowerShell Against Both On-Premises and Cloud Mailboxes

In an Exchange hybrid environment, there may times when you want to access both Exchange on-premises and Exchange Online mailbox attributes from within the same PowerShell session.

For example, let's say you want to create a report of all Exchange mailboxes that are on litigation hold, whether the mailbox is still in your on-premises Exchange or has been moved to Exchange Online.  Now, Azure AD Connect does sync some mailbox hold-related attributes from on-premises AD to Azure AD including “msExchLitigationHoldDate”, “msExchLitigationHoldOwner” and “msExchUserHoldPolicies”.  These are synced from on-premises mailbox-enabled users to corresponding Azure AD mail-enabled users.  We could simply query recipient objects in Azure AD (Get-Recipient) where LitigationHoldEnabled is True but that would just be too easy.  :-)

Querying mailboxes in both premises involves open a local Exchange PS session and then opening a remote Exchange Online PS session using the -Prefix switch on session import:

  1. Open an on-premises Exchange PowerShell session
  2. Connect Exchange Online remote PS:
    • $UserCredential = Get-Credential
    • $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
    • Import-PSSession $Session -Prefix O365
  3. Get-Mailbox | ft UserPrincipalName,DisplayName,LitigationHoldEnabled | ? {$_.LitigationHoldEnabled -eq $True}
  4. Get-O365Mailbox | ft UserPrincipalName,DisplayName,LitigationHoldEnabled | ? {$_.LitigationHoldEnabled -eq $True}

As you can see, I have used "O365" as the prefix on the Exchange Online cmdlets to distinguish between the two (you can use anything you’d like).  Steps 3 and 4 simply pull on-premises and Exchange online mailbox data, respectively.  If you wanted to combine the two queries, a simple example would be something like:

  • $mbxes = @()
  • $mbxes += get-mailbox | ? {$_.LitigationHoldEnabled -eq $True}
  • $mbxes += get-o365mailbox | ? {$_.LitigationHoldEnabled -eq $True}

Now $mbxes holds a complete list of mailbox objects that have litigation hold enabled, both on-premises and in the cloud. There are lots of ways you could combine the data and report on it.  This is just a very simple example and should give good direction on the capabilities.

There are also other uses for the -Prefix option such as when connecting to both Exchange Online and Security & Compliance Center remote PS sessions where there are overlapping cmdlets.