Microsoft.Graph Entra ID user list with licenses using Get-MgUser

Copper Contributor

In the Active user list (Active users - Microsoft 365 admin center) you can also find a column Licenses. This gives all licenses assigned to the user like this way: Microsoft 365 E3,PowerBiPro,Defender for Endpoint P1. Currently I have this code to get a list of the different properties, and this works fine. But I miss the object "Licenses". 



$UserLastEntraIDLoginData = Get-MgUser -All -Property 'AccountEnabled','City','Country','Department','DisplayName','JobTitle','UserPrincipalName','CreatedDateTime','SignInActivity' `
  | Select-Object @{N='AccountEnabled';E={$_.AccountEnabled}}, `
                  @{N='City';E={$_.City}}, `
                  @{N='DisplayName';E={$_.DisplayName }}, `
                  @{N='JobTitle';E={$_.JobTitle }}, `
                  @{N='UserPrincipalName';E={$_.UserPrincipalName}}, `
                  @{N='CreatedDateTime';E={$_.CreatedDateTime}}, `
                  @{N='LastInteractiveSignInDate';E={$_.SignInActivity.LastSignInDateTime}}, `

$UserLastEntraIDLoginData | Export-Csv -Path $env:USERPROFILE\users.csv -NoTypeInformation



I found this Get statement:



But with MGUserLicenseDetail, you get the Identifier and not as you get from the active user list:


Id                                          SkuId                                SkuPartNumber
--                                          -----                                -------------
gGD2lRZB1E-ucAiX8wQDO66cK8RP6rdKlxeBV2I1zKw c42b9cae-ea4f-4ab7-9717-81576235ccac DEVELOPERPACK_E5



This is what I want to get extracted from the user table:





Any suggestions?

1 Reply



Hi, Christaan.


You can't pull those long-text descriptive names that come from the Azure AD portal via Graph.


As you've already noted, the best you can get as the SkuId and the associated short code.


Microsoft does provide a table of skus and their associated descriptive name (linked below), however, the only approach this lends itself to is saving that table as your own CSV and uses that as a dictionary from which you can look up the AssignedLicenses (from the attribute of the same name on the Azure AD object).



I've taken your script and adapted it to look up the sku code (part number), but I have not gone that extra step to incorporate the long descriptive names. You should readily be able to adapt the example to do that if you prefer to.


$CsvFile = "$env:USERPROFILE\users.csv";

#region Prestage the known SKUs for this tenant. Doing this removes the performance overhead from making an extra call per user to Get-MgUserLicenseDetail.
# Endpoint documentation:
$SubscribedSkus = [System.Collections.Generic.Dictionary[[string],[string]]]::new();

(Invoke-MgGraphRequest -Method GET -Uri "").value |
    ForEach-Object {
        $Sku = [pscustomobject] $_;

        $SubscribedSkus.Add($Sku.skuId, $Sku.skuPartNumber);

#region Fetch the users, lookup any matching SKUs and export the results to CSV.
Get-MgBetaUser -All -Property 'AccountEnabled','City','Country','Department','DisplayName','JobTitle','UserPrincipalName','CreatedDateTime','SignInActivity', 'AssignedLicenses' |
    ForEach-Object {
        $Summary = [pscustomobject] @{
            AccountEnabled = $_.AccountEnabled;
            City = $_.City;
            Country = $_.Country;
            Department = $_.Department;
            DisplayName = $_.DisplayName;
            JobTitle = $_.JobTitle;
            UserPrincipalName = $_.UserPrincipalName;
            CreatedDateTime = $_.CreatedDateTime;
            LastInteractiveSignInDate = $_.SignInActivity.LastSignInDateTime;
            LastNonInteractiveSignInDate = $_.SignInActivity.LastNonInteractiveSignInDateTime;
            Licences = [System.Collections.Generic.List[string]]::new();

        foreach ($Entry in $_.AssignedLicenses) {
            if ($SubscribedSkus.ContainsKey($Entry.SkuId))
                # Add the friendly name if it's known.
                # Otherwise add the SkuId GUID. Note, not all SkuIds in Microsoft licencing have a friendly entry in the subscribedSkus endpoint, meaning this is an expected scenario.

        # You wouldn't normally do this next statement, but it's sadly necessary to avoid Export-Csv botching the list.
        $Summary.Licences = $Summary.Licences -join "`n";

    } |
        Export-Csv -NoTypeInformation -Path $CsvFile;