Entra / Microsoft 365 · Licensing
Report individual application licenses
An exmaple of how to report license assignments for applications like Forms or Teams assigned to users through license bundles like Office 365 E3.
Connect & set up
Run these once per session. All scopes are read-only unless the script makes changes.
Connect-MgGraph -Scopes "User.ReadWrite.All" -ErrorAction Stop
Run it
The main script. Copy it, or download the .ps1 and run it from your console.
Connect-MgGraph -Scopes "User.ReadWrite.All" -ErrorAction Stop# Define hash table of application licenses we might want to change - add more as you wish. Application identifiers and# plan identifiers can be found at https://docs.microsoft.com/en-us/azure/active-directory/enterprise-users/licensing-service-plan-reference$Plans = @{}$Plans.Add("Bookings", “199a5c09-e0ca-4e37-8f7c-b05d533e1ea2”)$Plans.Add(“Exchange Online", "efb87545-963c-4e0d-99df-69c6916d9eb0”)$Plans.Add("SharePoint Online", "be027f-2339-4123-9542-606e4d348a72”)$Plans.Add("Viva Engage", "7547a3fe-08ee-4ccb-b430-5077c5041653")$Plans.Add("Intune", "882e1d05-acd1-4ccb-8708-6ee03664b117")$Plans.Add("Teams", "57ff2da0-773e-42df-b2af-ffb7a2317929”)$Plans.Add("Forms", "2789c901-c14e-48ab-a76a-be334d9d793a”)$Plans.Add("Stream", "9e700747-8b1d-45e5-ab8d-ef187ceec156”)$Plans.Add("Planner", "b737dad2-2f6c-4c65-90e3-ca563267e8b9”)# Define the SKU identifiers for bundled plans we expect to search - again, you can add more if your tenant uses other plans$Skus = @{}$Skus.Add("cf50bae9-29e8-4775-b07c-56ee10e3776d", "Office 365 E5 No Teams")$Skus.Add("3271cf8e-2be5-4a09-a549-70fd05baaa17", "Microsoft 365 E5 No Teams")$Skus.Add("7e74bd05-2c47-404e-829a-ba95c66fe8e5", "Teams")$Skus.Add("6fd2c87f-b296-42f0-b197-1e91e994b900", "Office 365 E3")$Skus.Add("c7df2760-2c81-4ef7-b578-5b5392b571df", "Office 365 E5")$Skus.Add("26d45bd9-adf1-46cd-a9e1-51e9a5524128", "Office 365 E5 No Audio Conferencing")$PlanId = $null$Product = Read-Host "Enter the Office 365 application to report"$PlanId = $Plans[$Product]If ($null -eq $PlanId) { # Not foundWrite-Host ("Unable to find product {0} in our set of application SKUs” -f $Product) -ForegroundColor RedBreak} Else {Write-Host ("Product {0} found with SKU {1}” -f $Product, $PlanId) -ForegroundColor GreenWrite-Host "Looking for user accounts with that service plan"[guid]$PlanSearch = $PlanId[array]$Users = Get-MgUser -filter "assignedPlans/any(s:s/serviceplanid eq $PlanSearch)" -ConsistencyLevel eventual -CountVariable Test `-Property Id, displayName, userprincipalName, assignedLicenses, assignedPlans, department, country -All -PageSize 500}$PlanUsers = [System.Collections.Generic.List[Object]]::new()ForEach ($User in $Users) {[array]$UserPlans = Get-MgUserLicenseDetail -UserId $User.Id | Select-Object -ExpandProperty ServicePlans$Status = ($UserPlans | Where-Object {$_.ServicePlanId -eq $PlanId} | Select-Object -ExpandProperty ProvisioningStatus )[array]$LicenseNames = $NullForEach ($UserSku in $User.AssignedLicenses.SkuId) {$SkuProductName = $Skus[$UserSku]$LicenseNames += $SkuProductName}If ($null -ne $LicenseNames) {$ReportLine = [PSCustomObject] @{User = $User.DisplayNameUPN = $User.UserPrincipalNameDepartment = $User.DepartmentCountry = $User.CountrySKU = $PlanIdProduct = $ProductLicense = ($LicenseNames -join ", ")Status = $Status}$PlanUsers.Add($ReportLine)}}Write-Host "Total Accounts scanned:" $PlanUsers.Count$EnabledCount = $PlanUsers | Where-Object {$_.Status -eq "Success"}Write-Host (“{0} is enabled for {1} accounts” -f $Product, $EnabledCount.Count)$PlanUsers | Sort-Object User | Out-GridView
Attribution
Author
Office365itpros