Find all license-enabled groups in Microsoft Entra with PowerShell

This article walks you through how to use Microsoft Graph PowerShell to generate a report of all groups in your tenant with licenses assigned to them. This will help you build a better picture of how licenses are distributed in your organisation while maintaining performance using filtering.

I’m a huge fan of filtering with Microsoft Graph PowerShell, and earlier this month a post caught my eye which aimed to quickly obtain a list of groups in Microsoft Entra which have licenses assigned to them (group-based licensing). The problem was that the example did not use filtering and hence could potentially be quite cumbersome should the tenant contain a lot of groups, whether license-enabled or not. 

Requirements

Below are the necessary requirements to generate this group-based licensing report:

  1. You must have the following modules installed on your workstation: Microsoft.Graph.Authentication & Microsoft.Graph.Groups. See my post: How To Install the Microsoft Graph PowerShell Module.
  2. You must have access to a global administrator account to consent to the group.read.all permission in Microsoft Graph. For more info, see my post: How To Find Permissions For Microsoft Graph PowerShell.

PowerShell scripts to report license-enabled groups

To report all licensed enabled groups in your tenant, you must first connect to Microsoft Graph with the following Graph API permission scope:

  • Group.Read.All – Used to read all groups in your tenant.
  • Organization.Read.All – Used to get a like of all licenses available in your tenant.
Connect-MgGraph -scopes Organization.Read.All, Groups.Read.All

Then, to view a list of all groups that are assigned licenses, use the following example command.

Get-MgGroup -Filter "assignedLicenses/`$count ne 0" `
-CountVariable CountVar -ConsistencyLevel eventual

This example uses Advanced Filtering, which means that the processing of the filter, server-side, is handed by a dedicated service within Microsoft Graph and replicates its copy of data every minute. This ensures that advanced filters cannot impact the usual service provided by Microsoft Graph. To learn more about advanced filters and why the CountVariable and ConsistencyLevel parameters are required, check out my article ‘How to Use -Filter with Microsoft Graph PowerShell‘.

For a more detailed report, the following script will then loop through each group to obtain the license SKU part number and convert it into the readable part name.

Connect-MgGraph -scopes Organization.Read.All, Groups.Read.All

$properties = "displayName", "mailEnabled", "securityEnabled", "assignedLicenses", "groupTypes"

$skus = Get-MgSubscribedSku

$groups = Get-MgGroup -Filter "assignedLicenses/`$count ne 0" `
-CountVariable CountVar -ConsistencyLevel eventual -Property $properties | Select $properties

$groups | ForEach-Object {
    $licenses = @()
    Foreach ($l in $_.AssignedLicenses.skuid) {
        $license = $skus | Where-Object {$_.SkuId -like $l} | Select -expand SkuPartNumber
        $licenses += $license
    }
    $_.AssignedLicenses = $licenses -join ", "
}

You can then use the $groups variable to view the information.

View all groups
View all groups

Summary

Good housekeeping is important when it comes to licensing. Poorly kept and assigned licenses can quickly lead to a large amount of necessary cost and even compliance, in the event a licenses provide users access to tools that they should not be allowed to use. On my blog, I have various other Microsoft Graph PowerShell scripts you can use to help tidy up your licenses:

Daniel Bradley

My name is Daniel Bradley and I work with Microsoft 365 and Azure as an Engineer and Consultant. I enjoy writing technical content for you and engaging with the community. All opinions are my own.

Leave a Reply