Occasionally you may need to programmatically deduce the license level of a Microsoft Entra tenant to support identifying the available features. From the Microsoft Entra admin center, the license level can be one of three different values:
- Microsoft Entra ID Free
- Microsoft Entra ID P1
- Microsoft Entra ID P2
To identify your tenant version from the web portal, log in to https://entra.microsoft.com, then under Identity select Overview. If you are a standard user and your organisation uses the default Entra restrictions, you will be able to access the admin center, otherwise, if standard user access to the admin enter has been blocked, you will need any role assigned.
The version of your tenant will be listed next to the ‘License’ field on the Overview page.
Alternatively, you can use Microsoft Graph PowerShell to identify the Entra plan that is available in your tenant. To do this, you need to deduce if any of the licenses within your tenant contain the service plan named ‘AAD_PREMIUM_P2’. If any licenses contain this service plan, the tenant is assumed to be of Microsoft Entra ID Plan 2. If not, then you would look for AAD_PREMIUM (for Microsoft Entra ID Plan 1) and AAD_BASIC for (Microsoft Entra ID Free), which would always be true, if Plan 1 or Plan 2 are not present.
In an ideal world, I would like to use Microsoft Graph’s advanced filter capabilities to help deduce this information. An example of this would be like so, whereby we are filtering server side.
Get-MgBetaSubscribedSku `
-Filter "servicePlans/any(p:p/servicePlanName eq 'AAD_PREMIUM_P2')"
Unfortunately, these directory objects do not support advanced filters and instead, you are greeted with the following error: Get-MgSubscribedSku_List: Filtered searches against this resource are not supported. This is made clear in the documentation for the cmdlet.
The solution in this instance is to filter locally, which in reality is not so much of a performance hit considering the small amount of data needing to be downloaded from Microsoft Graph. The below example will get all licenses and store them in memory, then filter for any which contain the Microsoft Entra ID Plan 2 service plan, selecting only certain properties.
Get-MgSubscribedSku | ? `
{$_.ServicePlans.servicePlanName -contains "AAD_PREMIUM_P2"} | `
Select SkuPartNumber, CapabilityStatus, AccountName
Expanding on the above example, we can store all licenses into an array, then loop through each service plan to check if it is found in any of the licenses. If the service plan is found, then the loop will break, if none are found and the service plan is ‘AAD_BASIC’, then the license level is assumed to be Microsoft Entra ID Free, which it can only be if none of the premium service plans are found.
$items = @("AAD_PREMIUM_P2", "AAD_PREMIUM", "AAD_BASIC")
$Skus = Get-MgSubscribedSku
foreach ($item in $items) {
$Search = $skus | ? {$_.ServicePlans.servicePlanName -contains "$item"}
if ($Search) {
Write-host "Tenant is: $item" -ForegroundColor Cyan
break
} ElseIf ((!$Search) -and ($item -eq "AAD_BASIC")){
Write-host "Tenant is: $item" -ForegroundColor Cyan
break
}
}
By taking a programmatic approach to determining the license level, you can further report on only the features available within the level of Microsoft Entra ID found in the target tenant.