To get M365 group members in PowerShell, connect with PnP PowerShell and run Get-PnPMicrosoft365GroupMember with the group name. One line gives you every member’s name and sign-in address:
Get-PnPMicrosoft365GroupMember -Identity "Marketing Team" |
Select-Object DisplayName, UserPrincipalName
It returns the group’s direct members as user objects, so you can sort, filter or export them like any other PowerShell output.
In this tutorial, we’ll build the get M365 group members PowerShell scripts I actually use: members and owners with PnP, the same with Microsoft Graph and Get-UnifiedGroupLinks, a CSV export of every group, adding members, and finding which groups a user belongs to.
What do you need before you run these commands?
For PnP you need PowerShell 7 and the PnP.PowerShell module. If it isn’t on your machine yet, follow installing PnP PowerShell for SharePoint Online first.
Connect to any SharePoint site in the tenant. The group cmdlets talk to Microsoft Graph, so the site you pick doesn’t matter:
# Your own Entra ID app registration (Connect-PnPOnline needs a client ID)
Connect-PnPOnline -Url "https://spguides.sharepoint.com/sites/SPGuides" `
-ClientId "00000000-0000-0000-0000-000000000000" -Interactive
Your app needs the Graph permission Group.Read.All to read groups and members. If PowerShell says the cmdlet isn’t recognized, see how to fix Connect-PnPOnline is not recognized.
The old AzureAD module (Get-AzureADGroupMember) is retired, so don’t build new scripts on it. Use PnP, Microsoft Graph PowerShell or Exchange Online instead.
Get Microsoft 365 group members with Get-PnPMicrosoft365GroupMember
I created a demo group called SPGDemo Marketing Team with four members. Here’s the script that looks the group up and lists them:
$group = Get-PnPMicrosoft365Group -Identity "SPGDemo Marketing Team"
$members = Get-PnPMicrosoft365GroupMember -Identity $group.Id
$members | Select-Object DisplayName, UserPrincipalName, UserType |
Sort-Object DisplayName | Format-Table -AutoSize
"Members in $($group.DisplayName): $($members.Count)"

All four came back with UserType Member. Guests show Guest here instead, which is handy when you audit external access.
-Identity takes the group ID, the display name or the mail nickname. I pass $group.Id because two groups can share a display name, but an ID is always unique.
How do I get the owners of a Microsoft 365 group?
Owners are a separate list. A user can be an owner without being a member, so don’t assume the member list includes them:
Get-PnPMicrosoft365GroupOwner -Identity "SPGDemo Marketing Team" |
Select-Object DisplayName, UserPrincipalName
# Or get the group and its owners in one call
Get-PnPMicrosoft365Group -Identity "SPGDemo Marketing Team" -IncludeOwners |
Select-Object DisplayName, Mail, Visibility, CreatedDateTime,
@{ Name = "Owners"; Expression = { $_.Owners.DisplayName -join ", " } }

Miller is the only owner, and the group is Private. Group owners also own the connected SharePoint site; getting the SharePoint site owner with PowerShell covers that side.
Get group members with Microsoft Graph PowerShell (Get-MgGroupMember)
If your scripts already use the Microsoft Graph PowerShell SDK, you don’t need PnP at all. First find the group’s ID with Get-MgGroup, then read its members:
Connect-MgGraph -Scopes "GroupMember.Read.All"
$group = Get-MgGroup -Filter "displayName eq 'Marketing Team'"
# Members typed as users, so DisplayName and UserPrincipalName are filled in
Get-MgGroupMemberAsUser -GroupId $group.Id -All |
Select-Object DisplayName, UserPrincipalName
# Get-MgGroupMember returns every member type (users, devices, groups) as IDs
Get-MgGroupMember -GroupId $group.Id -All |
Select-Object Id, @{ Name = "Name"; Expression = { $_.AdditionalProperties.displayName } }
# Owners
Get-MgGroupOwner -GroupId $group.Id -All |
Select-Object @{ Name = "Owner"; Expression = { $_.AdditionalProperties.userPrincipalName } }
Get-MgGroupMember returns directory objects, so the name sits in AdditionalProperties. Get-MgGroupMemberAsUser skips that step for users. Add -All, or you only get the first page.
Building an app rather than a script? Power Apps reads the same member list through a connector; see getting Office 365 group members in Power Apps.
Get-UnifiedGroup members with Get-UnifiedGroupLinks (Exchange Online)
Exchange admins usually reach for Get-UnifiedGroupLinks. It needs the ExchangeOnlineManagement module and an Exchange Online connection:
Connect-ExchangeOnline -UserPrincipalName admin@spguides.onmicrosoft.com
# Members (default ResultSize is 1000, so ask for all)
Get-UnifiedGroupLinks -Identity "Marketing Team" -LinkType Members -ResultSize Unlimited |
Select-Object DisplayName, PrimarySmtpAddress
# Owners
Get-UnifiedGroupLinks -Identity "Marketing Team" -LinkType Owners
-LinkType is required and takes Members, Owners or Subscribers. Watch the default -ResultSize of 1000: a bigger group gets cut off silently unless you pass Unlimited.
Export all Microsoft 365 group members to CSV
For an audit, I loop through every group and write one row per member. Here’s the PnP version:
$groups = Get-PnPMicrosoft365Group
$rows = foreach ($group in $groups) {
foreach ($member in Get-PnPMicrosoft365GroupMember -Identity $group.Id) {
[PSCustomObject]@{
GroupName = $group.DisplayName
GroupEmail = $group.Mail
MemberName = $member.DisplayName
MemberEmail = $member.UserPrincipalName
UserType = $member.UserType
}
}
}
$rows | Export-Csv -Path ".\M365GroupMembers.csv" -NoTypeInformation -Encoding UTF8

In my tenant it wrote 394 rows from 121 groups in one run. The check at the end filters the file to the two SPGDemo groups, so you can confirm the columns before you open it in Excel.
Prefer Exchange Online? This version gives the same file from Get-UnifiedGroup:
Get-UnifiedGroup -ResultSize Unlimited | ForEach-Object {
$group = $_
Get-UnifiedGroupLinks -Identity $group.Identity -LinkType Members -ResultSize Unlimited |
Select-Object @{ Name = "GroupName"; Expression = { $group.DisplayName } },
DisplayName, PrimarySmtpAddress, RecipientType
} | Export-Csv -Path ".\M365GroupMembers.csv" -NoTypeInformation -Encoding UTF8
Both scripts make one call per group, so a large tenant takes a few minutes. For site-level permissions instead, see getting SharePoint site members with PowerShell.
Add members to an Office 365 group with PowerShell
Add-PnPMicrosoft365GroupMember takes one or more UPNs in -Users. I added Daniel to the demo Sales group:
Add-PnPMicrosoft365GroupMember -Identity "SPGDemo Sales Team" `
-Users "daniel@spguides.onmicrosoft.com"

The group went from 2 to 3 members right away. This cmdlet needs Group.ReadWrite.All, not just read access.
The Graph and Exchange equivalents look like this:
# Microsoft Graph PowerShell (scope GroupMember.ReadWrite.All)
$user = Get-MgUser -UserId "alex@spguides.onmicrosoft.com"
New-MgGroupMember -GroupId $group.Id -DirectoryObjectId $user.Id
# Exchange Online: add as member first, then as owner if needed
Add-UnifiedGroupLinks -Identity "Marketing Team" -LinkType Members `
-Links "alex@spguides.onmicrosoft.com", "adele@spguides.onmicrosoft.com"
With Add-UnifiedGroupLinks, a user must be a member before you can make them an owner. Guests can never be owners.
Once the membership is right, the group is a clean way to give access, for example by sharing a canvas app with a Microsoft 365 group.
How do I find which groups a user belongs to?
PnP has no reverse lookup, so this script checks each group’s members for one user:
$user = "mike@spguides.onmicrosoft.com"
$myGroups = foreach ($group in Get-PnPMicrosoft365Group) {
$members = Get-PnPMicrosoft365GroupMember -Identity $group.Id
if ($members.UserPrincipalName -contains $user) {
[PSCustomObject]@{ Group = $group.DisplayName; Visibility = $group.Visibility }
}
}
$myGroups | Sort-Object Group | Format-Table -AutoSize

Mike turned up in 3 groups: one public training group and the two private SPGDemo groups. In Power Apps you’d do this check in a formula instead, as shown in checking group membership in Power Apps.
With Microsoft Graph it’s a single call, because the user object knows its own memberships:
Get-MgUserMemberOfAsGroup -UserId "mike@spguides.onmicrosoft.com" -All |
Where-Object { $_.GroupTypes -contains "Unified" } |
Select-Object DisplayName, Mail
The Unified filter keeps Microsoft 365 groups and drops security groups. Like the member list, it shows direct memberships only.
Common errors and gotchas
One surprise I hit while testing: -IncludeSiteUrl failed on the demo group with a 403, even though I’m a tenant admin:

The same switch worked on a group I belong to. Drop it, or read the site URL from the admin side as shown in getting all SharePoint Online sites with PnP PowerShell.
- Nested groups are missing: all three methods return direct members only. Expand a member group yourself if your tenant nests groups.
- Only 1,000 members came back: add
-ResultSize Unlimitedto Get-UnifiedGroupLinks, or-Allto the Graph cmdlets. - Insufficient privileges: reading needs Group.Read.All (or GroupMember.Read.All); adding needs a ReadWrite scope.
- Add-UnifiedGroupLinks fails in an unattended script: Exchange can’t change group members over certificate-based app-only auth. Use Graph there.
Working on more Microsoft 365 group tasks? These guides pick up from here:
Frequently Asked Questions
How do I get members of a Microsoft 365 group in PowerShell?
Connect with Connect-PnPOnline and run Get-PnPMicrosoft365GroupMember -Identity “Group name”. With Microsoft Graph PowerShell, use Get-MgGroupMemberAsUser -GroupId -All; with Exchange Online, use Get-UnifiedGroupLinks -LinkType Members.
What is Get-UnifiedGroupLinks used for?
It lists the members, owners or subscribers of a Microsoft 365 group in Exchange Online. -LinkType is required, and -ResultSize defaults to 1000, so add Unlimited for big groups. See the Get-UnifiedGroupLinks reference.
How do I export Office 365 group members to CSV?
Loop through Get-PnPMicrosoft365Group (or Get-UnifiedGroup -ResultSize Unlimited), get each group’s members, build one object per member with the group name, and pipe the result to Export-Csv -NoTypeInformation.
Does Get-MgGroupMember return nested group members?
No. Microsoft documents it as direct members only, and it returns users, devices, contacts and groups as directory objects. The Get-MgGroupMember reference lists the permissions.
How do I add a user to an Office 365 group with PowerShell?
Run Add-PnPMicrosoft365GroupMember -Identity “Group name” -Users user@domain.com. Graph uses New-MgGroupMember -GroupId -DirectoryObjectId, and Exchange uses Add-UnifiedGroupLinks -LinkType Members -Links.

Hey! I’m Bijay Kumar, founder of SPGuides.com and a Microsoft Business Applications MVP (Power Automate, Power Apps). I launched this site in 2020 because I truly enjoy working with SharePoint, Power Platform, and SharePoint Framework (SPFx), and wanted to share that passion through step-by-step tutorials, guides, and training videos. My mission is to help you learn these technologies so you can utilize SharePoint, enhance productivity, and potentially build business solutions along the way.