Power Automate – Onboarding of new employees – part 2

In my previous post Power Automate – Onboarding of new employees – part 1 I looked at onboarding of new employees using a form and power automate. The process used an approval process, created the user and assigned the manager of said user.

The plan for this part is to automate the license step. Based on the information gathered we can assign the user the correct license. As license assignments go there are two ways. It is the manual way, where an individual need to assign the license (and control the service plan assignments) on a per user basis, or you can assign the license automatically using group assignments.

Both have benefits and drawbacks.

For small companies with few users, a manual license assignment can be sufficient. For larger companies and enterprises manual routines might be used, however it is not really recommended. One should always be mindful when choosing a strategy, as long as the human factor is present the error rate will usually be higher. If automation is used you will get a consistent result every time. Also with the new NCE license model companies are starting to us a combined strategy of fix and dynamically assigned licenses.
For instance a company can have 80% of it’s licenses assigned to the NCE yearly commitment and have 20% on a monthly license plan. This way they can easily change up and down the licenses within the 20%.

Using group assignment is generally a good strategy, though it can be hard to know if you have sufficient licenses available when using automation. So this is something that can be factored in when onboarding new users. You can get information if new licenses are required and order these, you can even schedule an email to your vendor to order a new license if it is required. In case your vendor have an API you can call, you can order directly in the flow and wait for the license to provision before continuing.

You can add a user to a group, the group will try to license the user and a license will be given to the user when it is available.
If you want to go more in-depth you can read about licensing here: Assign or remove licenses – Azure Active Directory – Microsoft Entra | Microsoft Learn

We have covered licensing, and I’m going to configure for a scenario where I will automate licensing based on group membership. As well we will need to have a “fail-safe” to notify someone (IT or Vendor) that a new license is required. Since I don’t have any vendors available I will send an email to an email address, I would love to be able to buy or update any licenses via Graph or from a 3rd party Partner. I don’t have access to one, so it’s really not an option.

So let’s cover the task in this scenario;

  • Check consumed licenses to determine if more licenses is needed.
    We will do this prior to assigning group membership, this way we don’t accidentally “order” to many licenses
    The original plan was to do this at the same time as you assign group membership. I’ve found that it is easier to break up the task in two steps and have reporting as it own step. I’ve reasoned that new users will be ordered in advance of their start, and since the organization can order users themselves the risk of having a user being created on the same day as they start is low.
  • Send email to an email address containing information with a purchase order (if the license count is exceeded)
  • Add the new user to a group – based on the license section from the form or list
    I’ll assume that the group used is licensing users

After some testing I’ve decided it’s easier to break the task into two steps, than to process everything in the same flow.

  1. Onboard the user and assign him the correct license group
  2. Create a reporting service using Logic App, report on groups that have errors assigning licenses, and a license status for each subscription
    Note the threshold can be assigned as you wish.

Step 2 can be used using Logic App/Automate or Azure Automation, however Logic App would be the easier step. You can still leverage Azure Key Vaults to keep secrets and you can also leverage managed identity. This will require an Azure Subscription.

This is the design I’ve come up with. Note you can create all this in the same tenant. I did the split because I didn’t have a subscription in my demo tenant, but using Graph and Azure Apps you can configure the reporting services against any tenant.

Step 1 – Onboard the User

My previous part Power Automate – Onboarding of new employees – part 1 requested the the user with an approval request and assigned the manager.

This version is updated to use a SharePoint list, but it uses the same principle. In theory you can do this app as an Logic App in Azure if you wanted to.

The flow starts similar to the other but with input into a List.
It all stars when the items is saved in the list, the flow starts. We get the managers email address (this step in a list is easier as we can use the reference field in Azure to populate the manager). This way we are not prone to typos in the email address.

Next we check that the managers account is active. If there are anything not right, the process stops and the user get’s an email with the error.

If all is good we continue in the same fashion as in part 1.
The main difference here is that I’ve added a switch after assigning the manager. The Switch is based on the value License in the List. It adds a user to that License group. As there can be only one group this seems to be the easiest way.

I noticed that I got an error when assigning a group to the user. I needed to add a Delay to the flow, the tasks happens quickly and everything doesn’t seem to be configured in time for the group assignment.
I used the License Value from the list. Based on the value we add it to the corresponding license group.

There is “nothing more to it” – it’s an easy way to request, approve, create and assign a license group to the user.
Now the next step would be to see if there are enough licenses. Onwards to the reporting.

Step 2- License reporting

What are the requirements to continue?
To be able to get the list of licenses we would leverage the Graph API. To use the Graph API we need permissions to read the required information from the API, and we do this by creating an Azure AD application with the correct applications.

To create an app, this article is a good place to start.
Create an Azure AD app and service principal in the portal – Microsoft Entra | Microsoft Learn

Create the app and give it a logical name. I used Contoso LicenseCheck

The next stem is to open API Permissions. You can remove User.Read and find the Organization.Read.All and Group.Read.All for the Graph API.
Remember you need to use Admin consent to approve this. The Organization.Read.All provides us with license information, the Group.Read.All let’s us read group information (and members). We are interested in groups that has license assignment failures.

We need to create a client secret and take a note of the Application ID, Client Secret and Tenant ID. We are going to store these in the Azure Key Vault at a later time.

I jump over to my Stellarlab Azure portal and start creating my services for Azure Key Vault and Logic App.

For the Azure Key Vault, be careful that you configure this correctly. I used it accessible with RBAC and enable the Managed Identity as a user role.

How to create an managed identity, I used the CLI to create my user-based-managed identity.
Managed identities for Azure resources – Microsoft Entra | Microsoft Learn
Manage user-assigned managed identities – Azure AD – Microsoft Entra | Microsoft Learn

These are the resources in my Azure Subscription and the secrets that I created in the key vault AKS-ReportingVault

We are using the Managed Identity and secrets from Azure Key Vault in the Logic App. This is good so we don’t need to store any secrets or sensitive information in the Logic App directly. The Logic app can be configured so that sensitive information is not displayed.

In this example the flow is not secured.

I start by importing the needed secrets to connect to the Graph API

Next we need to get the Authorization token to access the Graph API.
Once we get the result we parse that to a JSON object så we can create the Bearer token for the next part.

Getting the Authorization token

The schema used you can find in the Microsoft Learn documentation. I’ll attach it here so you can use it. You can also find it from Get access without a user – Microsoft Graph | Microsoft Learn

On the next bit you have a choice. You can start to split job or just pick one of the processes to run. The first one is checking subscriptions, returning consumed and active licenses. The second one is returning groups that has license issues, where action is needed. It does not return why the licensing has failed. As with the other job I parse the result so it is easier to work with later.

Subscribed SKUS

Get Subscribed SKUS

I also create a new variable to use as the token for later API calls.
Under you can see the result of the SubscriedSkus API. Now would we like to do something if we are at max consumedUnits?
Yes – if we are in an organization where there are raid changes in employees and users we would like to have a margin of error. Say we would like to get a warning at 90% or 95% consumed licenses.
As I said earlier many have a 80% / 20% subscription ratio, or 85% / 15%, having the monthly licenses provides some flexibility.

Get SubscribedSKUS response.

We parse the response from the Graph API and we use a filter condition to only list subscriptions with enabled licenses. No point in reporting on expired products. If you want to limit the filter to one or several subscriptions of a given type, you can use skuPartNumber for a specific subscription, for instance ENTERPRISEPREMIUM.

Now we need some variables that we are going to use to find the percentage of consumed licenses. All values are initialized as Float, you can use Integer, however you then need to be aware of the implications when writing the expressions to calculate the values. This is not my forte, I had a long and hard way to solve this next part. My suggestion is to use Float whenever you need numbers with decimal points.
I’ve set the License threshold value to 90%, above that value we want a notification. If you have few licenses you can adjust the threshold to fit your needs. You can also change it up and say if we have less than 3 licenses available we want to know about it. It’s not a part of this scope but it’s possible to do.

Variables

We start to loop through our filtered subscriptions and see if what values we are getting.
For each loops are processed simultaneously or in parallel, this caused me some headache and took some time to figure out.
There is a setting on For Each loop, press the (…) and select Settings. Make sure you enable Concurrency control and set the value to 1 (this is if you are running more than 1 subscription through the loop). Or you can get some interesting results.

I define Set variables and populate them with the correct values. When we set the LicensePercentage variable we use this expression
mul(div(variables(‘LicensesConsumed’),variables(‘LicensesEnabled’)),variables(‘Multiplier’))
What happens is that we multiply and divide. The calculations looks like this (ConsumedUnites/EnabledUnites) * 100

The response you get now is in percent and we can use that to do things. I’m using the threshold to mark when I send an email to alert of the status of the subscriptions. The entire for-each loop looks like this. You check if the percentage is higher than the threshold variable and trigger an email if it is.

All done for the license reporting. Onward to the groups with errors.

Member groups with errors

Next up is the API to get groups with members that has licensing errors. In this scenario we would always like to get a notification.
This can be to few licenses, it can be a user residing in two different licensing groups that have the same license or plans assigned to it.

We get the information about the group using the API and reuse the Token we have gotten before.
Endpoint: https://graph.microsoft.com/v1.0/groups?$filter=hasMembersWithLicenseErrors+eq+true
The input and output looks like this. We need to parse the object so that we can use it for later. We use the ParseJSON and enters the body.

Group with licensing errors

You can find the schema below.

Final bit is to run a for each loop so we can process the groups and send the information by email. “That is all there is to it”.

It took some time to figure some of this things out. Hope you have a good use for them!

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.