Enhancing the Script with Group Membership and Mailbox Permissions

I previously wrote about a PowerShell script created to help organizations assess the work required to perform a tenant-to-tenant migration. The script gathers a lot of detailed information that is invaluable when planning a migration project. One of the key aims of the script was that it should not take multiple hours to run in a standard medium size environment (with a few thousand users) – as such, I omitted some items to save time while still capturing key preliminary information.

Based on feedback, I have now added two additional pieces of functionality as optional items – a Group Membership report and a Mailbox Permission report.

A Note on Permission Changes

With the original scope, the only permissions required to gather data were read-only Microsoft Graph permissions and the Global Reader management role. Unfortunately, these permissions do not allow the PowerShell script to run the ‘Get-RecipientPermission’ Exchange Online cmdlet.

To enable the script to get recipient permissions, I added the Exchange Administrator role to the Prepare-TenantAssessment.ps1 script. If you do not require the permissions report, you can remove the role by removing lines 173 – 187 of the preparation script.

On Demand Migration

Migrate all your workloads and Active Directory with one comprehensive Office 365 tenant-to-tenant migration solution.

Running the PowerShell Script with Optional Parameters

As mentioned above, there are two new optional items in the assessment script. Running the script as normal generates the same output as before. However, if you add the  -IncludeGroupMembership and -IncludeMailboxPermissions parameters (as shown in Figure 1), two new tabs will be added to the report with detail about group members and mailbox permissions, respectively.

Strengthening your Microsoft 365 Tenant-to-Tenant Migration PowerShell Script
Figure 1: Adding the new optional parameters will provide extra detail in the output file

Including Group Membership

With the -IncludeGroupMembership parameter, the output file contains the tab “Group Membership”. This tab (Figure 2) contains a list of group memberships (capturing Users, Service Principals, and Groups) in the tenant. The Group ID and name are listed along with the ID of the member, their name, their User Principal Name and the type of object, and their membership type. This data gives a detailed record of group membership that can be used to form an import file for creating groups and adding members in the new tenant. Nested Groups are not expanded but are listed with the MemberObjectType of Group.

Strengthening your Microsoft 365 Tenant-to-Tenant Migration PowerShell Script
Figure 2: The Group Membership tab details all group members in the tenant

Mailbox Permissions

Similarly, the -IncludeMailboxPermissions parameter adds the tab “Mailbox Permissions” to the output file. This tab (Figure 3) contains a list of all Full Access and Send-as permissions for all user and shared mailboxes in Exchange Online. The usual details of the source object are included along with the individual permission and the user to which permissions are granted. This information can be invaluable during a hectic migration weekend where mailbox permissions usually get overshadowed by data migration activities. Outside of migrations, the report can be used to outline what permissions exist in the environment.

Strengthening your Microsoft 365 Tenant-to-Tenant Migration PowerShell Script
Figure 3: The Mailbox Permissions tab details all Full Access and Send-as permissions present in Exchange Online

Everything Comes at a Cost

The additional data about group membership and mailbox permissions is useful to have. However, nothing comes for free. The additional data gathering extends the run time of the PowerShell script significantly, particularly in larger environments. To help monitor progress, both the Group Membership and Mailbox Permissions tasks use the progress bar to indicate how much work is left to do (Figure 4).

Strengthening your Microsoft 365 Tenant-to-Tenant Migration PowerShell Script
Figure 4: The progress bar reports on a per-item level for the optional features

The features are optional so if you need a high-level assessment, just omit the -IncludeGroupMembership and -IncludeMailboxPermissions parameters.

Always More to Do

Group Membership and Mailbox Permissions were two of the items people have asked to be included in the PowerShell script, and they are valuable to have when assessing any migration. There are many more features and metrics that can be gathered for consideration in a tenant migration scenario, so I encourage you to make suggestions. Maybe you’ve already added functionality yourself which provides some interesting additions? It is always worthwhile sharing your experience and improvements with the community by voicing your ideas!

About the Author

Sean McAvinue

Sean McAvinue is a Microsoft MVP in Office Development and has been working with Microsoft Technologies for more than 10 years. As Modern Workplace Practice Lead at Ergo Group, he helps customers with planning, deploying and maximizing the many benefits of Microsoft 365 with a focus on security and automation. With a passion for creative problem solving, he enjoys developing solutions for business requirements by leveraging new technologies or by extending the built-in functionality with automation. Blogs frequently at https://seanmcavinue.net and loves sharing and collaborating with the community. To reach out to Sean, you can find him on Twitter at @sean_mcavinue


  1. Deepak Tripathi

    Where is the download link of the script

  2. Pawel

    Hello Sean
    referring to Mailbox Permission section: “This tab (Figure 3) contains a list of all Full Access and Send-as permissions for all user and shared mailboxes in Exchange Online.” – what about Send on Behalf permission?
    why this permission is not included in your script?

  3. Clément BONNIN

    I found the issue. There was a space character before the @ of a user email address. My colleague did some mistakes..
    Anyway now the script is running fine but I don’t see anything after discoverysearchmailbox in the mailbox permissions tab of the Excel file generated.
    If it helps, in the High-level tab, “User mailboxes” count is ok but “Exchange data size” not at all.

    For comparison I use FlyServer from Avepoint company which is free for the inventory part of the M365 migrations.
    But your Excel reports are more detailed so I’m still interested 🙂

  4. Clément BONNIN

    Hello, thanks for this update !
    I tested but unfortunately, I have this error :

    Get-EXORecipientPermission : Error while querying REST service. HttpStatusCode=401 ErrorMessage={“error”:{“code”:”Unauthorized”,”message”:”User is not allowed to call
    Get-RecipientPermission”,”innererror”:{“message”:”User is not allowed to call Get-RecipientPermission”,”type”:”Microsoft.Exchange.Admin.OData.Core.ODataServiceException”}}}
    Perform-TenantAssessment.ps1:690 : 40
    + … rmissions = Get-EXORecipientPermission $mailbox.UserPrincipalName | …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : Erreur de protocole : (:) [Get-EXORecipientPermission], RestClientException
    + FullyQualifiedErrorId : An error occurred while processing this request.,Microsoft.Exchange.Management.RestApiClient.GetExoRecipientPermission

    Do you know how to solve this ?

    1. Sean McAvinue

      Hi Clément,
      Can you confirm you downloaded and ran the latest version of the preparation script? There are permission modifications added to the preparation that are required for the “Get-EXORecipientPermission” cmdlet.

      1. Clément BONNIN

        Hi Sean, thanks for the answer.
        Sorry, I didn’t saw there was an update on the preparation script too..
        Anyway I tried to used the latest version of the preparation script but unfortunately I have this error message :

        Error preparing script:
        The property « ResourceAccess » was not found in this object. Check it exists and it can be defined.
        Check Prerequisites

        I tried to remove the app on Azure just in case but nope.
        If you have an idea.

        1. Clément BONNIN

          I figure it out partially using PowerShell Console instead of PowerShell ISE but I have an error for Exchange :

          Get-EXOMailboxPermission : Impossible de valider l’argument sur le paramètre «UserPrincipalName». L’argument «» ne correspond pas au modèle «[a-zA-Z0-9!#$%*+\-/?^_`.{|}~]+@([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,4}». Indiquez un argument qui correspond à «[a-zA-Z0-9!#$%*+\-/?^_`.{|}~]+@([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,4} et réessayez. Perform-TenantAssessment.ps1:673 : 75
          + … ilboxPermission -UserPrincipalName $mailbox.UserPrincipalName | ? { $ …
          + ~~~~~~~~~~~~~~~~~~~~~~~~~~
          + CategoryInfo : InvalidData : (:) [Get-EXOMailboxPermission], ParameterBindingValidationException
          + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.Exchange.Management.RestApiClient.GetExoMailb

          I think there is a special username with a bad character or something else.

          1. Sean McAvinue

            Possibly a bad character alright, Does the report export with one user missing?

Leave a Reply