Monitor Licenses with the License Provisions Checker

Published by Valentin Mazhar on , last updated on

Share

This is probably one of the most recurring topics in the Power Platform: Licensing. Instead of discussing the various plans available, or whether making Managed Environments more accessible could actually bring more benefits to both Microsoft and their customers, we’ll jump right into a very practical question:

How can CoEs and tenant Admins maintain an oversight over Power Platform Licenses?

Different types of licenses, different prices based on the quantity purchased, this can be a challenge. You will have understood it from the title… I built a solution to make it slightly easier, meet the License Provisions Checker!

Screenshot of the Licenses page of the License Provisions Checker App

Platform Improvements Underway

Let’s start by acknowledging that things are better today than they used to be. Fairly recently Microsoft released in the Billing>Licenses page in the Power Platform Admin Center (PPAC). Still in preview, this provides admins with a place where they can monitor most licenses across the platform and different license types.

Screenshot of the licenses page from the PPAC

This is definitely a great improvement for Admins to have a quick oversight on the licenses in the tenant. Let’s now look at what is still missing, otherwise there wouldn’t be any sense to use the License Provisions Checker… 🙄.

Current Challenges for License Management

In this post we will distinguish two main types of licenses:

  • User Licenses: purchased and assigned to users. This the case for the Power Apps Premium and Power Automate Premium licenses for example.
  • Addons: purchased as capacity addons and adding to the capacity pool for a specific service. This is the case for AI Builder Credits, Copilot Studio Message for example.

The fact that there are different types of license is not necessarily a problem in itself for Admins though. Let’s start by reviewing the challenges that organizations might face to manage Power Platform licenses.

Not a Central Place for Monitoring

Ideally, Admins would only need to go to a single page to view all licenses. Unfortunately this is still not the case today. Even though we are getting closer with the Licenses page in the PPAC, this page still does not show all licenses, such as Dataverse Storage Addons, AI Builder Credits or Process Mining Capacity. These capacity addons are only in display in the PPAC capacity page.

For someone responsible for the Power Platform in an organization, having an immediate oversight over all Power Platform related licenses in a central place would be very helpful.

Multiple Skus For a Same License

When purchasing Addons, it is common to have different prices based on the quantity purchased. From a more technical point of view, it means that different license skus can relate to the same addon. Here is an example for the AI Builder Credits:

Screenshot showing several Skus for AI Builder

This means that if an organization purchases 30 packs of AI Credits over the years, they might have purchased different skus at different prices.

Unfortunately Microsoft does not make it so easy to identify the actual Skus purchased for Power Platform Admins. For a Global Admin it should be possible to see previous purchases from the M365 Admin Center, but a “simple” Power Platform Tenant Admins wouldn’t have access to this information.

Why does this matter? Because having the detail of the purchased Skus could help identify opportunities to optimize costs. For example if over the months/years a company purchased multiple AI Builder Packs with the T1 plan and get to more than 10 packs purchased, they might want to decommission them later and purchase the T2 plan instead to get a better deal.

Quantity of Purchased Sku Units does not match Quantity of Addons

Looking at the AI Builder example from above, AI Builder Capacity Addons are purchased by Packs. In this case, purchasing 1 sku unit actually provides 1M AI Builder Credits. In addition, it is common to have some addons provided by other licenses. Still with the example of AI Builder, each Power Automate Premium license automatically provisions some AI Credits in the tenant.

So the quantity of Sku units purchased does not always match the quantity of addons provisioned on the tenant. Both pieces of information are important: the quantities of purchased sku units defines how much an organization pays, and the quantities of addons in the tenant defines how much of the related service, is available, but they are not accessible from the same place.

Expiring Skus are Easy to Miss

Purchased license sku units can have different “states”. They can be in an Enabled, Warning, Suspended or Locked Out state. This is how Microsoft defines these states in the official documentation:

Screenshot showing the different sku states

Let’s consider that an organization purchased 5000 Power Apps Premium licenses over the years and have assigned all of them. At the end of the year, they made a mistake and did not renew 300 licenses. These 300 licenses will therefore first move to a “warning” state before being suspended. Identifying these licenses quickly while they still are in the warning state can be key to prevent unexpected suspension and operational issues.

This information is accessible in the Microsoft Entra ID for user licenses, but is not so easy to access for addons for a Power Platform Admin.

License Sku Technical Name, Addon Technical Name, and License Name do not match

On a positive note, all the purchased Sku Units can be accessed with the Graph API List subscribedSkus request. This is great as it can fill many gaps, and it is actually one of the sources I am using in the License Provisions Checker which I share further below. There are two main properties returned which can be used to identify the actual license it relates to: SkuId and SkuPartNumber.

The SkuId is a GUID and the SkuPartNumber can be considered as a technical name to identify the license. These properties always remain the same for a given Sku, probably for technical reasons. The name of the license however… Well, we all know what happens with product and license names, they change. For example, this is how we get to a situation today where the SkuPartNumber property for the Power Automate Premium license is “POWERAUTOMATE_ATTENDED_RPA”.

This is not all! The actual addons provisioned in the tenant also have a technical name which do not match with the sku nor the license name. For example, the Copilot Studio Messages license’s skuPartNumber property is “Power_Virtual_Agents” and the related addon technical name is “MCSMessages”.

Even though this is not a problem for most people, this is challenging for anyone who wants to build a custom solution to facilitate license management (me!).

No Possibility for Custom Reporting OOB

As we have seen, most of the information is available somewhere but from different interfaces. However, even if all the data was available from a central place, not being able to access the raw data easily to make custom reports can be a challenge.

Storing the data in a custom location could allow to add more metadata and build custom reports to support strategic decisions.

No History

Having a clear view over how many licenses are provisioned today is great, but being able to look at the past and identify trends is even better. All the interfaces and tools available to Power Platform Admins today only show the current state.

Looking at the past evolution could help estimate the future consumption and optimize costs.

Potential Organizational Challenges

This last challenge is the only one that is not only technical, but also organizational. For many large organizations, the person/team responsible for the Power Platform is not the one actually responsible to purchase the licenses. There can be multiple teams involved between the Power Platform admin and the person who purchases the license. It can make it challenging for the CoE to remain informed in a timely manner about purchases and changes in license provisions.

Receiving automated alerts when such changes happen could go a long way to resolve this.

The License Provisions Checker to the Rescue

I built the License Provisions Checker to address all the above challenges. It is not perfect and is only a first version, you can find it in my GitHub Repository below:

Screenshot of the Licenses page of the License Provisions Checker App

More technical information about how to set up the solution is available in my GitHub repo, but here is how the solution works from a functional point of view.

Overview

This is a fairly simple solution, it’s main purpose is to automatically gather all the relevant information about the license provisions in the tenant and store it in Dataverse. More specifically, it allows to:

  • Extract the Power Platform purchased license skus and addon quantities on a daily basis,
  • Inform a defined email address of any change in quantities of enabled, warning, suspended or locked out sku units,
  • Keep a history of previous license quantities,
  • Navigate through the collected data with a Model Driven App.

All the data is automatically maintained by cloud flows. Every day a daily flow runs to pull the purchased sku units and addons information from the tenant. The Licenses table shows an overview of licenses and Addons, and the Purchased Skus table shows the detail of the individual purchased skus. The License History shows former snapshots of license quantities to easily report on the evolution of license provisions over time.

  • Screenshot of the Licenses page of the License Provisions Checker App
  • screenshot of the license main form
  • screenshot of the license history view

When there is a change in sku unit quantities, an email is sent to a defined mailbox to communicate the changes. All unit quantity changes are communicated, except a change in the consumed units, to avoid spamming as such changes are expected to be frequent (whenever a user leaves the company or requests a license). This way the Admins are alerted when an sku unit is purchased, about to expire, or suspended.

screenshot of an email sent by the license provisions checker

Data Model

The solution relies on 3 tables: License, Purchased Sku, and License History. These three tables are automatically maintained with cloud flows presented further below.

Purchased Sku Table

This table contains the details of all the purchased license skus in the tenant. They correspond to the individual product plans purchased from the M365 Admin Center, and are extracted leveraging the Graph API List subscribedSkus request.

This table contains the information below:

  • Name: think of it as the display name for the sku
  • Sku Part Number: used to identify the Sku purchased
  • Related License: lookup to the related license, as several skus can be related to a same license, such as the AI Builder example from above,
  • Units Enabled, Units Warning, Units Consumed, Units Suspended, Units Locked Out: as described above in this post and on Microsoft documentation.
  • Units Consumed: for user licenses, this corresponds to the licenses assigned to users. For Addon licenses, this value is always 0 in the Graph API, and null in the License Provisions Checker. This makes sense, as one unit of an addon is often a pack of addons.

License Table

This table contains the information related to the licenses in the tenant. As explained above, one license might correspond to one or more skus. It contains the information below:

  • Name: display name for the license.
  • License Type: the type of the license, either User or Addon.
  • Product: the product related to the license.
  • Addon Name: when the license is an Addon, this column contains the Addon technical name, which is use to pull the quantity of addons provisioned and allocated for this license.
  • Addons Allocated, Addons Provisioned: the quantity of addons allocated and provisioned in the tenant for this license. This information is gathered using the Power Platform Licensing API (more information further below).
  • Total Enabled Units, Total Warning Units, Total Consumed Units Total Suspended Units, Total Locked Out Units: these columns sum the related sku columns. They are updated by low code plugins each time a purchased sku is created, updated or deleted.
  • Total Quantity Provisioned: number of licenses provisioned in the tenant
    • For user licenses, this is the sum of the Total Enabled Units and the Total Warning Units
    • For addons, this is Addons Provisioned
  • Total Quantity Allocated: number of allocated user licenses or addons
    • For user licenses, this corresponds to the Total Consumed Units
    • For addons, this is the Addons Allocated
  • Total Quantity Available: the quantity provisioned minus the quantity allocated.

License History Table

This table contains snapshots of the License table to maintain history of former license quantities. It mostly contains the same total quantity and total units columns as the License table presented above. In addition, it also contains:

  • Snapshot Date: the date when the snapshot was taken.
  • Related License: lookup to the related license. This helps to access information about the the license type, addon name etc. which are not replicated.
  • Name: the name of the license at the time of the snapshot (anticipating some name changes as we are so accustomed to!).

Cloud Flows

The solution only contains 3 flows:

  • Lpc – Prepopulate Licenses: this flow is a one-off flow which populates the Purchased Sku and License tables. Running this flow once will add and configure 27 skus and their related 19 licenses. The key is to link the Skus and their related license together, as well as to indicate the sku part number and the addon technical names. Without these properties, the solution will not work as expected.
    Although Microsoft presents most skus and thei related sku part number in this page, they are still not all included. They are also not including the addons technical names. I created this flow to facilitate the set up by including the values for most licenses and skus related to the Power Platform. I did not include the trial nor the D365 licenses.
  • Lpc – Daily Provision Checker: this flows runs every day and pulls the information of the purchased sku using the Graph API. It also pulls the data related to the addons in the tenant using the Power Platform API. Finally, it sends an email with relevant changes in purchased sku units to an email address defined by an environment variable.
  • Lpc – Take License Snapshot: regularly, this flow runs and copy the information from the License table into the License History table to take a snapshot of the situation. It does not copy the detailed of each purchased sku, but does contain the aggregated information included in the license table.

Getting Data from the Graph API

To get the purchased skus data from the Graph API, an App needs to be registered in Azure with the appropriate API Permissions (LicenseAssignment.Read.All or Organization.Read.All for example). The solution is configured in a way which requires application permissions and not delegated. The solution is also configured to leverage Azure Key Vault to avoid hard writing the client ID and secret in a variable or in the flow.

More information about the steps required to set everything up can be found on my GitHub repo.

Getting data from the Power Platform Licensing API

To get the quantities of purchased and allocated addons in the tenant, the Power Platform Licensing API is used. This deserves a bit more information as not all of what is used is officially supported as of today.

Two Documented Power Platform APIs

There are two Power Platform API versions.

  • A first version of the API was released a few years ago, relying on the host “https://api.bap.microsoft.com/”. This reached GA a while ago.
  • A more recent version was then released with the host “https://api.powerplatform.com/”. It is still in preview today and is the API used by the “Power Platform for Admins V2” connector.

This latest API version is designed to allow to take any action available from the PPAC, as per Microsoft’s statement:
screenshot showing Microsoft statement about the Power Platform API
Looking at the documentation though, we can see that only two licensing operations are documented (which use the term “currency” for what we call “addon” in this post):

  • Get Currency Allocation By Environment:
    GET https://api.powerplatform.com/licensing/environments/{environmentId}/allocations?api-version=2022-03-01-preview
  • Patch Currency Allocation By Environment:
    PATCH https://api.powerplatform.com/licensing/environments/{environmentId}/allocations?api-version=2022-03-01-preview

A Third, Non-Documented API

When we open the PPAC capacity page we can see that a different operation is executed to show the report at tenant level of the addons provisioned and allocated:
GET https://licensing.powerplatform.microsoft.com/v0.1-alpha/tenants/{tenantId}/CurrencyReports

This API is not part of the latest Power Platform API, even though it relates to something possible from the PPAC. We could therefore expect it to be included in the future. Regardless, for the time being,⚠️this API does not appear to be supported / documented by Microsoft⚠️. It is the same one that I use in the PPAC reports extractor to automatically download and report on tenant consumption reports on a daily basis. As always, using non-supported APIs is at your own risk as it might stop working at any time.

What is interesting is that following the Microsoft instructions to authenticate with the Power Platform API also allows to authenticate to the Licensing API, which comes handy in this situation 😁.

As for the Graph API, the License Provisions Checker is configured to use an App Registered in Azure and Azure Key Vault. The difference for this API is that a Power Platform Administrator Service Principal also needs to be set up instead of granting API permissions, more information about this in my GitHub repo.

Other Solution Components

There are two main other types of component in the solution:

  • A JavaScript function is called in the main form of the License table. It is used to hide/show the Addon-related fields based on whether the license is an addon or a user license.
  • 3 Low Code Plugins are used to update the Total Sku Units quantity of the License Table. Roll up could be used instead but they are not refreshed straight away. Even Though Power Automate could also be used, I opted for the Low Code Plugins as I find that it has better performance. These plugins are executed when an Sku is created, updated or deleted.

Comments & Recommendations

A few comments and recommendations:

  • Start with the pre-populate flow and add/remove Skus and License as needed. Only the Skus and Licenses present and configured in the table will be updated by the solution.
  • To add new licenses and skus in the App:
    • Start by creating the license. If it is a user license, you only need to add the license name and license type (product is optional). If it is an Addon, you will need to find the Addon technical name. You can do so by opening the developer tools and opening the PPAC Capacity page, then identify the network request “CurrencyReports”.
    • Then add the Skus. You will need to define a name, the related license and the sku part number. You can find most skus in this Microsoft page, but not all. If you cannot find the relevant sku, you can open the M365 Admin Center and follow the step to purchase the sku. You can then use the developer tools on the sku details page to identify the sku part number, with the network request “buyDisplayDetails”.
  • Use Power BI to report on the data as needed.
  • Dataverse Storage Addons (Files, Database, Log) are not returned by the Power Platform Licensing Request. Therefore at the moment the License Provision Checker does not show the Quantities provisioned in the tenant, only the purchased sku units. Another request should be used for this, I might add it in a future release.
  • I shared another solution in the past to automatically download and report on the actual tenant consumption reports on a daily basis. These two solutions are complementary. I haven’t brought them together yet, but I will likely do this in the future to have the full story on a single Power BI report.
  • This first version does not include any costs information yet. This would be an easy extension to add the unit cost of each purchased sku in the table. This would allow to automatically calculate the the total costs of licenses and addons in the App.
  • Let me know what you think! It is always a great experience when people reach out to me about the solutions I share. Let me know if it helps and if some changes could make it even more helpful, I have already made several improvements in the other solutions thanks to the received feedback so far.

Share
Categories: Governance

0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *