Trying to get a list of users with their licenses and specific security group membership.
I have the following:
# Retrieve all users with licenses
$licensedUsers = Get-MgUser -Property ID, DisplayName, UserPrincipalName, AssignedLicenses -ConsistencyLevel eventual -All | Where-Object { $_.AssignedLicenses.Count -gt 0 }
#
# Initialize an array to store results
$results = @()
# Loop through each licensed user
foreach ($user in $licensedUsers) {
# Get assigned license SKUs
$licenseTypes = $user.AssignedLicenses | ForEach-Object { $_.SkuId }
# Get security group memberships where the group name starts with "bg_"
$groups = Get-MgUserTransitiveMemberOf -UserId $user.Id -All | Where-Object { $_.ODataType -eq '#microsoft.graph.group' -and $_.SecurityEnabled -eq $true -and $_.DisplayName -like 'bg*' } | Select-Object -ExpandProperty DisplayName
# Store the data in results
$results += [PSCustomObject]@{
UserID = $user.Id
DisplayName = $user.DisplayName
UserPrincipal = $user.UserPrincipalName
LicenseTypes = $licenseTypes -join ", "
SecurityGroups = $groups -join ", "
}
}
# Output the results in table format
$results | Format-Table -AutoSize
# Export to CSV
# $results | Export-Csv -Path "LicensedUsersWithSecurityGroups.csv" -NoTypeInformation -Encoding UTF8
I get all the user info, but the group info is blank.
If I remove:
| Where-Object { $_.ODataType -eq '#microsoft.graph.group' -and $_.SecurityEnabled -eq $true -and $_.DisplayName -like 'bg*' } | Select-Object -ExpandProperty DisplayName
I get "Microsoft.Graph.PowerShell.Models.MicrosoftGraphDirectoryObject" as the group.
What am I missing?
TIA
The issue with your code is that the objects outputted from Get-MgUserTransitiveMemberOf
don't have those properties you're trying to filter on, they're actually inside a dictionary property named AdditionalProperties
, so the actual filter should be:
$groups = Get-MgUserTransitiveMemberOf -UserId $user.Id -All |
Where-Object {
$props = $_.AdditionalProperties
$props['@odata.type'] -eq '#microsoft.graph.group' -and
$props['securityEnabled'] -and
$props['displayName'] -like 'bg*'
} | Select-Object -ExpandProperty DisplayName
You should also avoid the use of $results = @()
and $results += ...
, see this Q&A: Why should I avoid using the increase assignment operator (+=) to create a collection for more info.
In summary, your code should be:
# $results = @() <- Remove this
$results = foreach ($user in $licensedUsers) { # <- Put it here, `$results =`
$licenseTypes = $user.AssignedLicenses
$groups = Get-MgUserTransitiveMemberOf -UserId $user.Id -All |
Where-Object {
$props = $_.AdditionalProperties
$props['@odata.type'] -eq '#microsoft.graph.group' -and
$props['securityEnabled'] -and
$props['displayName'] -like 'bg*'
}
[PSCustomObject]@{ # <- Remove `$results +=`
UserID = $user.Id
DisplayName = $user.DisplayName
UserPrincipal = $user.UserPrincipalName
LicenseTypes = $licenseTypes.SkuId -join ', '
SecurityGroups = $groups.DisplayName -join ', '
}
}