Forum Discussion
See groups menbership of a list of users
Hello,
I'm trying to get a list from all groups that a user is part of, on a single file (DL, Teams groups, ...)
This is what I'm doing:
What am i doing wrong?
Thank you.
Hi,
The easy answer is that you're trying to get the UserPrincipalName of the Group rather than the user, which returns null because the group doesn't have a UserPrincipalName.
As the variable $_. has already been overwritten by Get-AzureAdUsermembership you can't really reference back.
I have written a Powershell script that would do the job and shared it on Github:
Check it out and let me know if it fits your requirements.
EDIT: Apparently I was too slow and LainRobertson already came with a more modern solution!
- LainRobertsonSilver Contributor
Basically, you need to capture the user's details such as id, userPrincipalName, etc. in the outer loop, before proceeding to the inner loop to fetch the group/object details.
I started earlier with one answer but decided to switch Azure modules (to a more "recent" one) and have a play. The example below is the result, where it pulls any kind of membership - not just groups. I've also added a flag called IsDynamicGroup since that's usually something you want to know when figuring out how someone ended up in (or out) of scope for a given group.
The key additional inclusion from testing in my tenant is that it pulls Azure AD role memberships - which is quite nifty to know when working with PIM-style auditing. You can always filter this out client-side (or just take it out of the script altogether if you like.)
For context, this script uses the following first-party Microsoft Azure modules:
- Microsoft.Graph.Authentication
- Microsoft.Graph.DirectoryObjects
- Microsoft.Graph.Users
It uses the Graph beta endpoint, which you can select using the following command:
Select-MgProfile -Name "beta";
Example script
Get-Content -Path "D:\Data\Temp\Test.txt" | ForEach-Object { Get-MgUser -UserId "$_" -ExpandProperty TransitiveMemberOf -Select Id, UserPrincipalName, TransitiveMemberOf } | ForEach-Object { # We're now in your per user "outer" loop. $User = $_; $User.TransitiveMemberOf.Id | ForEach-Object { # Whereas now, we're in your per user membership inner loop. Here, we're iterating through each one of their memberships and pulling the Azure AD object details below. Get-MgDirectoryObject -DirectoryObjectId "$_" | ForEach-Object { # This is yet another nested level we reach after having pulled the object for which the user is a member. [PSCustomObject] @{ UserId = $User.Id; UserPrincipalName = $User.UserPrincipalName; ObjectId = $_.id; ObjectType = $_.AdditionalProperties["@odata.type"].Split('.')[-1]; ObjectName = $_.AdditionalProperties["displayName"]; MailEnabled = $_.AdditionalProperties["mailEnabled"]; SecurityEnabled = $_.AdditionalProperties["securityEnabled"]; IsDynamicGroup = if ($null -ne $_.AdditionalProperties["groupTypes"]) { $_.AdditionalProperties["groupTypes"].Contains("DynamicMembership") } else { $null }; } } } } | Export-Csv -Path "D:\Data\Temp\test.csv" -NoTypeInformation -Encoding Unicode;
Example output (having removed the Export-Csv in order to see this)
Cheers,
Lain
- LainRobertsonSilver Contributor
I also meant to add that you mentioned Exchange groups, however, if you use dynamic Exchange groups, you can't pull that from Azure AD. You'd need to use the Exchange Online module to fetch those and their memberships.
Cheers,
Lain
- CatarinagmCopper ContributorThank you so much for your answer and help.
I used:
Connect-Graph -Scopes User.ReadWrite.All, Organization.Read.All
Select-MgProfile -Name "beta"
but still getting this privileges error:
Get-MgDirectoryObject : Insufficient privileges to complete the operation.
At line:13 char:21
+ Get-MgDirectoryObject -DirectoryObjectId "$_" |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: ({ DirectoryObje...ndProperty = }:<>f__AnonymousType2`3) [Get-MgDirectoryObject_Get1], RestException`1
+ FullyQualifiedErrorId : Authorization_RequestDenied,Microsoft.Graph.PowerShell.Cmdlets.GetMgDirectoryObject_Get1
Get-MgDirectoryObject : Insufficient privileges to complete the operation.
At line:13 char:21
It never asked me for any tenant credentials.- CatarinagmCopper ContributorPS C:\WINDOWS\system32> Get-MgDirectoryObject -DirectoryObjectId xxxx
Id DeletedDateTime
-- ---------------
xxx
I have the permissions to run it individually
- raindropsdevIron Contributor
Hi,
The easy answer is that you're trying to get the UserPrincipalName of the Group rather than the user, which returns null because the group doesn't have a UserPrincipalName.
As the variable $_. has already been overwritten by Get-AzureAdUsermembership you can't really reference back.
I have written a Powershell script that would do the job and shared it on Github:
Check it out and let me know if it fits your requirements.
EDIT: Apparently I was too slow and LainRobertson already came with a more modern solution!
- CatarinagmCopper Contributorraindropsdev Thank you so much it worked perfectly since i'm not used to use graph yet.
Lifesaver. Thank you!- raindropsdevIron Contributor
I'm happy my code was helpful!
That said, be aware that the AzureAd module will reach end of life at the end of this year, so it's strongly discouraged to put anything new in production using it.
To assist I've also prepared a Graph API version of that same script and updated the Azure AD with parameters to customize input and output paths and filename:
Strong recommendation NOT to just use it as is though. Read it and understand why everything was one as is and learn it so you can do it yourself next time for the next task you need to do with MgGraph.
P.S: to find equivalent cmdlets you can use this table: https://docs.microsoft.com/en-us/powershell/microsoftgraph/azuread-msoline-cmdlet-map?view=graph-powershell-1.0