Manage Microsoft 365 Group Memberships with Graph PowerShell

Managing and auditing Microsoft 365 Groups and their memberships is a crucial task for administrators. Having a clear overview of which users belong to which groups is essential for maintaining access controls and ensuring proper collaboration settings within an organization. This guide walks you through a Graph PowerShell script designed to list all Microsoft 365 Groups along with their members, providing administrators with a streamlined way to audit group memberships.

The Script:


    # Ensure the Microsoft Graph PowerShell module is installed and imported
    if (-not (Get-Module -ListAvailable -Name "Microsoft.Graph")) {
        Install-Module -Name "Microsoft.Graph" -Scope CurrentUser
    }
    Import-Module Microsoft.Graph

    # Function to list all groups with their members
    function Get-AllGroupsWithMembers {
        try {
            # Retrieve all M365 Groups
            $groups = Get-MgGroup -All

            foreach ($group in $groups) {
            Write-Host "Group: $($group.DisplayName)"
            Write-Host "Group ID: $($group.Id)"

            # Retrieve all members of the group
            $members = Get-MgGroupMember -GroupId $group.Id

            if ($members.Count -eq 0) {
                Write-Host "No members in this group." -ForegroundColor Yellow
            } else {
            foreach ($member in $members) {
            # Check if the member has a UserPrincipalName (for users) or fallback to DisplayName or Id
                if ($member.UserPrincipalName) {
                    Write-Host "Member: $($member.UserPrincipalName)"
                } elseif ($member.DisplayName) {
                    Write-Host "Member: $($member.DisplayName)"
                } else {
                    Write-Host "Member ID: $($member.Id)"
                }
             }
            }

            Write-Host "--------------------------------------"
            }
        } catch {
            Write-Host "Error retrieving groups and members: $($_.Exception.Message)" -ForegroundColor Red
        }
    }

    # Run the function
    Get-AllGroupsWithMembers

How the Script Works

This PowerShell script utilizes the Microsoft Graph PowerShell module to retrieve a full list of all Microsoft 365 Groups and their members. Here’s how each part of the script functions:

  • Module Import and Installation: The script ensures that the Microsoft Graph PowerShell module is installed and loaded. This module is required for interacting with Microsoft Graph APIs via PowerShell.
  • Retrieve All Groups: The Get-MgGroup -All cmdlet fetches all available Microsoft 365 Groups in the tenant. For each group, the script prints out the group's name (DisplayName) and its unique identifier (Id).
  • Retrieve Group Members: Using the Get-MgGroupMember cmdlet, the script retrieves all members for each group, printing out relevant member information. The script checks for three possible member attributes:
    • UserPrincipalName (usually for users).
    • DisplayName (for other types like service principals).
    • Id (as a fallback in case no display name is available).
  • Display the Results: If emails from the specified sender are found, they are displayed in a table format showing the subject and received date. If no emails are found, the script informs you that no matching emails exist in the mailbox.
  • Handle Empty Groups: If the group has no members, the script prints a message stating, "No members in this group."

This script is designed to handle various member types, ensuring that the correct data is displayed for each.

Further Enhancements

There are several ways to further enhance this script based on your administrative needs:

  • Export Group Memberships to a CSV File: If you'd like to store the group membership information for reporting purposes, the script can be extended to export the output to a CSV file instead of just printing it to the console.
  • 
        $report = @()
        foreach ($group in $groups) {
            foreach ($member in $members) {
                $report += [PSCustomObject]@{
                GroupName   = $group.DisplayName
                MemberName  = $member.UserPrincipalName ?? $member.DisplayName ?? $member.Id
            }
          }
        }
        $report | Export-Csv -Path "C:\path\to\GroupMembers.csv" -NoTypeInformation
    
  • Filter Groups by Type: You can modify the script to list only specific types of groups, such as Unified groups, security groups, or public/private groups.
  • $groups = Get-MgGroup -Filter "groupTypes/any(g:g eq 'Unified')" -All
  • Include Group Owners: Extend the script to also retrieve and list the owners of each group by using Get-MgGroupOwner:
  • $owners = Get-MgGroupOwner -GroupId $group.Id
  • Scheduled Reporting: Automate the script to run on a schedule (using Windows Task Scheduler or Azure Automation) to generate regular group membership reports.

Frequently Asked Qusetions

  • Can I add both users and service principals as group members using Graph PowerShell?
  • Yes. Microsoft Graph allows adding users, service principals, and even other groups as members, depending on the group type. Make sure to pass the correct object reference (e.g., /users/{id} or /servicePrincipals/{id}) in your request body.

  • How can I verify if a user is already part of a group before adding them?
  • Use the Get-MgGroupMember cmdlet to retrieve existing members and check if the user’s Id already exists. This prevents duplicate additions and potential errors during bulk membership operations.

  • Is it possible to automate membership synchronization across multiple groups?
  • Yes. You can script a loop to compare group memberships and automatically add or remove users based on a master source (like a CSV file or another group). This approach is ideal for maintaining consistent access controls.

  • What permission is required to manage group memberships via Graph PowerShell?
  • You’ll need the Group.ReadWrite.All permission. Ensure that your app or user account has this delegated or application-level permission before performing add or remove operations.


Possible Errors & Solutions

  • Error: Insufficient Permissions: If you encounter a permissions error, ensure that your app registration or service account has the required Graph API permissions, specifically Group.Read.All or Group.ReadWrite.All. Run Connect-MgGraph -Scopes “Group.ReadWrite.All” to apply for the permission.
  • Error: Rate Limiting: If you're retrieving a large number of groups and members, you may hit Graph API rate limits. In such cases, consider implementing retry logic or using a batching approach.
  • Timeout Errors: If the script takes too long and times out, try optimizing it by adding filters to only fetch relevant groups or members, reducing the amount of data being retrieved in a single run.

📋 Check Group Membership Type Before Modification

Before adding or removing members, verify whether the group is Microsoft 365, Security, or Mail-enabled using the GroupTypes property.

Only Microsoft 365 groups (with "Unified" type) sync with Teams and Outlook — meaning membership updates directly impact collaboration tools.
⚙️ Bulk Membership Updates Simplify Large-scale Management

When managing large user sets, use CSV-based imports with cmdlets like New-MgGroupMemberByRef in a loop.

This approach helps administrators efficiently onboard or offboard users across multiple groups — especially during department migrations or org restructures.

Conclusion

This script provides a simple yet powerful way for administrators to audit Microsoft 365 Group memberships across the organization. By leveraging Microsoft Graph PowerShell, admins can efficiently retrieve and display group and member information, ensuring proper access control and group management. With further customization, such as exporting data to CSV or scheduling regular reports, this script can become a key part of your Microsoft 365 administration toolkit.

Feel free to adapt the script based on your specific needs, and let it help you streamline your group management tasks!

Suggested Reading

© m365corner.com. All Rights Reserved. Design by HTML Codex