Tag Archives: power-platform

Using GraphLicenseManager to generate license reports…

Microsoft 365 administrators utilize a variety of tools to manage and monitor license usage and assignments. In the Microsoft 365 Admin Center administrators often review and export a list of users assigned to the different SKUs within their tenant. This is done by selecting Billing -> Licenses -> and selecting a license.

The export button allows the administrator to export to CSV the list of users assigned the license. I have recently spoken with several customers that have noticed that the export has changed the information provided. For example, in prior releases of the Microsoft 365 Admin Center the export contained the field Blocked Users (Account Enabled). This field, along with many others, are no longer present in the download offered through the portal.

With the evolving changes in the Microsoft 365 Admin Center surrounding license management and assignment the interfaces previously responsible for providing this data have been deprecated. With this deprecation arose the need to change the fields contained in the download. Unfortunately, this is not something that is administratively configured.

In order to generate the data previously available I have added functions to the GraphLicenseManager to generate the CSV files. In addition to providing some of the missing fields, I have provided an interface that allows administrators to select all single value attributes returned by get-MGUser.

To begin utilizing the GraphLicenseManager:

Set-ExecutionPolicy Unrestricted

Install-Module GraphLicenseManager

When the graph license manager is installed, the process starts with:

Start-GraphLicenseManager -logFolderPath c:\temp

The graph license manager is a combination of PowerShell and Windows Forms. When the start command is executed the login screen is displayed.

On the logon screen a TenantID is required to establish the graph connection. This can easily be obtained from the EntraID properties in the Entra Portal. To establish permissions either certificate authentication or interactive credentials may be utilized. For those interested in setting up certificate-based authentication for Microsoft Graph see:

Use Certificate Authentication for Microsoft Graph

In the selected operation drop down select “License Assignment Report”. If you are a customer in a different graph environment, use the graph environment selection dropdown to select the environment.

The license report requires a minimum of two permissions:

  • Directory Permission: Organization.Read.All
  • User Permission: User.Read

When using interactive credentials, the user may select any of the roles they qualify for. It is important to note that when establishing the graph connection if the permissions requested are not already assigned to the user an administrator may be required to provide consent to the permissions.

After selecting the authentication method, operation type, and required permissions the Connect Microsoft Graph button completes the connection.

When the connection has completed successfully the License Assignment Report wizard is displayed.

Selecting the Sku Name drop down allows the administrator to view all license assignments associated with all user skus in the tenant. The list updates dynamically with each SKU selected.

The properties dialog allows the administrator to select properties. The refresh button applies the administrator selections to the information displayed for each user.

To retain the data displayed the Export to CSV button may be utilized. When selected all data shown in the users view is exported to a CSV file within the log file directory. If exporting multiple SKUs a CSV file is created for each sku selected. NOTE: If exporting the same sku with different values any previous export for the same sku is overwritten.

When completed the exit button closes the Graph License Manager.

Using the Graph License Manager administrators can produce a variety of customized reports expanding on the information previously offered in the Microsoft 365 Admin Center.

Using graph to modify group based licenses…

Microsoft Graph provides the ability to modify licenses assigned to groups when implementing group-based licensing. The command set-MGGroupLicenses is utilized to modify the license template assigned to a group.

Set-MGGroupLicense

When creating a license template to apply or modify on the group a bodyParameters switch is utilized. Building the bodyParameters by hand can often be tricky. In this post I want to break down the structure of the bodyParameters and demonstrate how this can be built easily with Powershell.

The bodyParameters starts with a hash table that contains two array entries. The add licenses array and the remove licenses array. (Black box in figure below).

The add licenses array is an array of hash tables. (Green Box). Each hash table entry in the array is a combination of an array of plans to disable (Purple Box) and the skuID associated with those plans (Blue Box).

The remove licenses array is an array of skuIDs to remove from the group. (Red Box).

This is what the structure looks like in Microsoft’s sample documentation.

On the current group is the Office 365 A1 for Students License. This license needs to be replaced with the Microsoft 365 E5 licenses with the Information Barries and Microsoft 365 Phone System plans disabled. I also want to add the entire Microsoft 365 Defender for Office 365 (Plan 2) license.

To recap

  • Remove Licenses
    • Office 365 A1 for Students = 314c4481-f395-4525-be8b-2ec4bb1e9d91
  • Add Licenses
    • Microsoft 365 E5 = 06ebc4ee-1bb5-47dd-8120-11324bc54e06
      • Disable Microsoft 365 Phone System = 4828c8ec-dc2e-4779-b502-87ac9ce28ab7
      • Disable Information Barriers = c4801e8a-cb58-4c35-aca6-f2dcc106f287
    • Microsoft Defender for Office 365 (Plan 2) = 3dd6cf57-d688-4eed-ba52-9e40b5468c3e

To build the body parameters utilize in the set-MGGroupLicenseCommand:

#Establish the body parameters hash table.
$params = @{}

#Build the add licenses array
$addLicenses = @()

#Build the remove licenses array
$removeLicenses = @()

#************************************************************************

#Build the disabled plans for the first license to be added.

$disabledPlans = @()
$disabledPlans += "4828c8ec-dc2e-4779-b502-87ac9ce28ab7"
$disabledPlans += "c4801e8a-cb58-4c35-aca6-f2dcc106f287"

#Set the skuID for the first license.

$skuID = "06ebc4ee-1bb5-47dd-8120-11324bc54e06"

#Build the hash value for the added licenses.

$skuHash = @{"DisabledPlans" = $disabledPlans ; "SkuID" = $skuID}

#Add the skuHash to the array of licenses to add.

$addLicenses += $skuHash

#************************************************************************

#Build the second entry to the add licenses.

#Build the disabled plans for the second license to be added.

$disabledPlans = @()

#Set the skuID for the first license.

$skuID = "3dd6cf57-d688-4eed-ba52-9e40b5468c3e"

#Build the hash value for the added licenses.

$skuHash = @{"DisabledPlans" = $disabledPlans ; "SkuID" = $skuID}

#Add the skuHash to the array of licenses to add.

$addLicenses += $skuHash

#************************************************************************

#***********************
#At this time all licenses to be added have been built and added to the addArray.
#***********************

#Update the licenses to remove with the decomissioned plan.

$removeLicenses += "314c4481-f395-4525-be8b-2ec4bb1e9d91"

#***********************
#Complete the params has table.
#***********************

$params = @{"AddLicenses" = $addLicenses ; "RemoveLicenses" = $removeLicenses}

In some instances, discovering the SKU and PLAN ids utilized in the body parameters configuration can also be challenging. One of the methods I like to use to simplify process is to create a standard user in Microsoft 365 and apply the license template to the user. The license template would be the same as the template I want to assign to the group. The user can then be utilized as a template for completing the body parameters build.

#Obtain the user that has the license template to be applied.

$licenseTemplateUser = get-mgUser -userID licenseTest@domain.onmicrosoft.com -Property AssignedLicenses

#Establish the body parameters hash table.
$params = @{}

#Build the add licenses array
$addLicenses = @()

#Build the remove licenses array
$removeLicenses = @()

#************************************************************************

#Build the licenses to be added.

foreach ($sku in $licenseTemplateUser.AssignedLicenses)
{
    write-host ("Processing skuID: "+$sku.skuID)

    #Set the SKUID

    $skuID = $sku.skuID

    if ($sku.disabledPlans.count -gt 0)
    {
        write-host "The sku has disabled plans - creating disabled plans."

        foreach ($plan in $sku.disabledPlans)
        {
            write-host $plan
            $disabledPlans+=$plan
        }
    }
    else
    {
        $disabledPlans=@()
    }

    #Build the hash for the sku.

    $skuHash = @{"DisabledPlans" = $disabledPlans ; "SkuID" = $skuID}

    #Add the has to the add licenses array.

    $addLicenses += $skuHash
}

#Set any licenses to be removed.

$removeLicenses += "314c4481-f395-4525-be8b-2ec4bb1e9d91"

#***********************
#Complete the params has table.
#***********************

$params = @{"AddLicenses" = $addLicenses ; "RemoveLicenses" = $removeLicenses}

I hope that outlining the structure of the bodyParameters simplifies utilizing graph for group based license administration.