Поделиться через


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.

Comments

  • Anonymous
    September 21, 2017
    Exactly what I needed. Works like a charm. Thank you!
  • Anonymous
    February 27, 2018
    Hi,is there a way to combine these commands in order to identify which users are hosted in the cloud and which are on premise? For example I would like to filter users with Exchange Online, so I can assigned them a specific attribute in AD.
    • Anonymous
      March 02, 2018
      Sure, you should be able to do something like:$mbxes = @()$mbxes += get-mailbox -resultsize unlimited$mbxes += get-o365mailbox -resultsize unlimitedThe variable $mbxes would then contain a list of all mailboxes, both on-premises and Exchange Online. You should be able to identify which mailboxes are where based on a number of attributes on the objects such as database, servername, MicrosoftOnlineServicesID, etc.If you are in a hybrid configuration and have either migrated your mailboxes to Exchange Online or initially provisioned them as remote mailboxes, you could also use the Get-Recipient cmdlet on-premises and filter on the RecipientTypeDetails attribute (UserMailbox vs. RemoteUserMailbox).