Microsoft 365 Group Based licensing automated

If you have already total control of your licenses in your Microsoft tenant, this article is not for you. But what we see with a lot of customers though, is that they do not have the insight and control they need to be on top of this. So I was thinking I should try to automate this. I started looking into Microsoft Graph to see what information that is available regarding licenses available in the tenant and found that MS Graph has us covered on this. So I started out in Microsoft Graph Explorer do dig into what data is available. Start with the following GET query in graph explorer:

Querying Microsoft Graph API


This first call to graph will list out all information about the license SKU’s that excists in your tenant. You will have information like consumed units, skupartnumber (name) and the different service plans available within that sku. Lets take a simple example like Visio Plan 2 (Previous Visio Pro Online):

            "capabilityStatus": "Enabled",
            "consumedUnits": 7,
            "id": "d99c3e0a-5a04-4bda-95a1-da0c24b731ee_c5928f49-12ba-48f7-ada3-0d743a3601d5",
            "skuId": "c5928f49-12ba-48f7-ada3-0d743a3601d5",
            "skuPartNumber": "VISIOCLIENT",
            "appliesTo": "User",
            "prepaidUnits": {
                "enabled": 7,
                "suspended": 0,
                "warning": 0
            "servicePlans": [
                    "servicePlanId": "da792a53-cbc0-4184-a10d-e544dd34b3c1",
                    "servicePlanName": "ONEDRIVE_BASIC",
                    "provisioningStatus": "Success",
                    "appliesTo": "User"
                    "servicePlanId": "2bdbaf8f-738f-4ac7-9234-3c3ee2ce7d0f",
                    "servicePlanName": "VISIOONLINE",
                    "provisioningStatus": "Success",
                    "appliesTo": "User"
                    "servicePlanId": "113feb6c-3fe4-4440-bddc-54d774bf0318",
                    "servicePlanName": "EXCHANGE_S_FOUNDATION",
                    "provisioningStatus": "Success",
                    "appliesTo": "Company"
                    "servicePlanId": "663a804f-1c30-4ff0-9915-9db84f0d1cea",
                    "servicePlanName": "VISIO_CLIENT_SUBSCRIPTION",
                    "provisioningStatus": "Success",
                    "appliesTo": "User"

The first thing we see is that the skuPartNumber and the naming inside your Azure AD portal is not the same. Visio Plan 2 in the Azure AD Portal has the skuPartNumber: “VISIOCLIENT”.  If we look further in the data we see that we have the serviceplans ONEDRIVE_BASIC, VISIOONLINE, EXHANGE_S_FOUNDATION and VISIO_CLIENT_SUBSCRIPTION. This does not match with the names in our AzureAD Portal. Also in the Azure Portal the “hidden” service plan EXCHANGE_S_FOUNDATION is not even listed, as it probably is a required prerequisite that can’t be removed.

This means we should need to map out this SKU’s and Service Plans to the “human language” if we want our groups to have naming that the admins of the tenant can understand. I am not catering for the service plans in this blogpost and I will always enable all services plans under each SKU in the script I am using. To get insight into what SKU equals what License I have used this page for reference. It seems to be almost complete: . I then used this information to make a mapping table inside my script. Here are a short example, the full table will be inside the script shared at the end:

A simple approach

This method I am using here is a great place to start on your journey to group based licensing. But if you have addons that has requirements for other SKU’s you most probably will need to do more scripting. What I am doing in this blogpost is to create a group for each subscribed License Sku available in your tenant that has the capabilitystatus = enabled and is assignable to a user. If the capabilitiystatus does not have the status as enabled, that subscription is expired or deactivated. The logic I have built here is pretty simple, gather all licenses, create a group for each of them and assign the license to this newly created group. Sounds simple, right?

I also decided I wanted to do all of this with 100 % MS Graph Api calls, authenticating with app based auth (ClientID/ClientSecret). This means I do not need any modules or service accounts if I want to run this as a recurring job for instance in Azure Automation in my environment to cater for new licenses bought. I have a separate function for handling the MSGraph Authentication inside the script. This blogpost does not cover the creation of the Azure AD App i have used, but the API permissions you need for this is:

Microsoft Graph Permissions

  • Application – Group.ReadWrite.All – To be able to read and create groups
  • Application – Organization.Read.All – To be able to read out the licensing information from your tenant.

Remember to give Admin Consent to the API Permissions.

I am using the following MS Graph API Calls:


To give you a quick demonstration I have recorded a quick demonstration on how this would work running the script:

The Script

To run the script we need the following information:
  1. Your tenant ID or Directory ID from Azure AD
  2. An Azure AD App Registration
    1. The APP/Client ID for the APP
    2. A Client Secret for Authentication

Download Script

Jan Ketil Skanke

Jan Ketil is an Enterprise Mobility MVP since 2016 and are working as a COO and Principal Cloud Architect at CloudWay in Norway. He has been in the industry for more than 20 years working for both Microsoft Partners and Microsoft. He loves to speak about anything around Enterprise Mobility and Secure Productivity. He is also the lead for the community conference Experts Live Norway. Jan Ketil has presented at large industry conferences like Microsoft Ignite, Microsoft Ignite The Tour, Microsoft Inspire, Experts Live Europe, Techmentor HQ (3rd best session 2019) and NIC Conference in Oslo.

Add comment


Categories use cookies to ensure that we give you the best experience on our website.