Disable Password Expiration for Service Users in Azure AD

with a Logic App running at least privileges

Christopher Brumm
4 min readSep 18, 2021

Recently I had the challenge to set a Password Policy for a lot of Service Users in Azure Active Directory to enable a migration from Pass-through Authentication to Password Hash Sync.

First attempt with the AAD standard methods

The first prototype of my Logic app was built very quickly and I knew again why I like Logic apps so much 😍:

Picture 1: The first attempt

On closer inspection, however, I noticed that my quickly created Logic app with the ready-made actions from the AAD connector clashed quite strongly with my ideas about the required rights.

If you create a Logic App as a Global Admin that uses the AAD connector actions, you will quickly find yourself in a Consent Dialog that asks for the following permissions:

Picture 2: The permissions for the AAD connector 😲

In order to reduce the rights, I shortly considered creating a function user that only has the role of user admin — but then I quickly discarded this, as it all felt rather wrong to me.

The least privilege version

Slightly shocked by the handling of administration rights, I looked around for alternatives — thanks again for your advice Thomas — and then built a version that uses the HTTP method and the managed identity of the Logic App.

Compared to a functional user, the managed identity offers the advantages of being bound to this Azure resource and being able to be authorized very granularly.

Picture 3: The permissions we really need

Step by Step Guide

A group for the service user

The basis for my Logic App is an AAD group. Since there is of course a consistent naming convention for the service accounts, a dynamic group can be used in my case.

Picture 4: Dynamic group for service user

A new Logic App

Create a Logic App like in this example. If you create a new LA the system assigned managed identity is already enabled. You can check this and get the object ID in the section identity of the LA.

Picture 5: System assigned managed identity


The next step is to assign the permissions we really need (see picture 3):

  • User.ReadWrite.All -> to set the Password Policy
  • GroupMember.Read.All -> to read the group members

Unfortunately, it is not yet possible to assign these permissions via GUI, but fortunately there is this script by Laura Kokkarinen that solves the problem.

Simply fill the variables $miObjectID with the object ID of the managed identity and $permissionsToAdd with the above-mentioned permissions.

Some logic for the Logic App

The last step is to add some logic to the Logic App. My goal at this point was to read out the memberships of a given group and set the password policy for each service user if not already set.

Picture 6: The better approach

The big difference to the first version is that instead of the AAD actions, the HTTP action is now used. This allows us to use the managed identity, but requires us to deal a little with the MS Graph (Group Members, Get User and Update User) and the use of the Parse JSON action to make the result evaluable.

The system-assigned managed identity can then simply be selected in the HTTP action:

Picture 7: Authentication in HTTP action

If you want to use my example you can download it on GitHub — you just have to insert the ID of your group into the variable ServiceUser