All pages referring or tutorials for Microsoft Entra.
This is the multi-page printable view of this section. Click here to print.
Microsoft Entra
- Get notifications when Entra ID break glass admins are used
- How to properly secure Break Glass Accounts in your Entra ID
- Solved - ADSync service stopped (Entra Connect Sync)
- Match AD users using Entra Connect Sync and MSGraph
- Implement Certificate-based authentication for Entra ID scripts
- Audit your Entra ID user role assignments
- Audit your privileged Entra ID applications
- The Zero Trust-model
- How to solve DeletingCloudOnlyObjectNotAllowed error Entra Connect Sync
- Dynamic group for access to Windows 365
Get notifications when Entra ID break glass admins are used
As we want to secure our Break Glass Accounts as good as possible, we cloud want to get alerts when break glass admins are used to login. Maybe they are used on a daily basis, or are being attacked. When we configure notifications, we instantly know when the accounts are being used and can check why a login has taken place.
In this guide we will configure this without Microsoft Sentinel. If you already have a Sentinel workspace, the recommended action is to configure it there and to configure a automation rule/playbook.
The alert solution described
The solution we will configure looks like this:
- Log Analytics Workspace
- Set diagnostic settings for Entra ID sign in logs to write to Log Analytics
- Set query to find successful or non-succesful sign in attempts (based on your needs)
- Set Azure Monitor alert to alert admins of the attempts taking place
- After all this we will test this to test if this works as excpected
Here we use all the features inside Azure only, and no 3rd party solutions.
Step 1: Configure Log Analytics Workspace
We will start configuring our Log Analytics Workspace in Azure. This can be simply described as database for logs and metrics. Using specific queries, we can pull data our of it to use in dashboards, workbooks and like we do now; Alert rules.
Login to the Azure Portal and search for “Log Analytics Workspace”:

Click on “+ Create” to create a new workspace.

Select the desired resource group and give it a name and create the workspace.
After the workspace is configured, we can configure the data retention and daily cap of the Log Analytics Workspace. As ingesting a lot of data could be very expensive at the end of the month, you could configure some caps. Also, we will only ingest the data needed for this solution, and nothing more.

Here I have set the daily cap to 1 gigabyte max per day, which would be more than enough for this solution in my case. In bigger environments, you could set this to a higher value.
Step 2: Configure Sign in logs to Log Analytics
Now we need to configure the Sign in logs writing to our Log Analytics Workspace. We will do this through the Entra admin center: https://entra.microsoft.com.
Go to “Monitoring and Health” and then to “Diagnostic Settings”

On there, click on “+ Add diagnostic setting”

On this page, give the connector a describing name, select SignInLogs on the left and on the right select “Send to Log Analytics workspace” and then select your just created workspace there.

Then click the “Save” button to save this configuration. Now newly created sign in logs will be written to our Log Analytics workspace, so we can do further investigation.
Data ingestion notes
Quick note before diving into the log analytics workspace and checking the logs. When initially configuring this, it can take up to 20 minutes before data is written to the workspace.
And another note, sign in logs take up to 5-10 minutes before showing in the Portal and before written to Log Analytics.
Step 3: Configure the query
In this step we need to configure a query to search login attempts. We can do this by going to our Log Analytics Workspace in Azure, and the go to “Logs”.
We can select a predefined query, but I have some for you that are specific for this use case. You can always change the queries to your needs, these are for example what you could search for.
- To get all successful login attempts for one specific account:
SigninLogs
| where UserPrincipalName == "account@domain.com"
| where ResultType == 0
| project TimeGenerated, UserPrincipalName, IPAddress, Location, ResultType, ResultDescription, ConditionalAccessStatus, AuthenticationRequirement
| sort by TimeGenerated desc- To get all unsuccesful login attempts for one specific account:
SigninLogs
| where UserPrincipalName == "account@domain.com"
| where ResultType != 0
| project TimeGenerated, UserPrincipalName, IPAddress, Location, ResultType, ResultDescription, ConditionalAccessStatus, AuthenticationRequirement
| sort by TimeGenerated desc- To get all login attempts, successful and unsuccesful:
SigninLogs
| where UserPrincipalName == "account@domain.com"
| project TimeGenerated, UserPrincipalName, IPAddress, Location, ResultType, ResultDescription, ConditionalAccessStatus, AuthenticationRequirement
| sort by TimeGenerated descNow we know the queries, we can use this in Log Analytics and set the query type to KQL. Paste one of the queries above and change the username to get the results in your tenant:

Now we have a successful login attempt of our testing account, and we can see more information like the source IP address, location, if Conditional Access was applied and the resulttype. Resulttype 0 means a successful login.
You could also use the other queries, but for this solution we need to use query one where we only search for successful attempts.
Step 4: Configure the Alert
Now that we have a successful query, we need to configure a alert rule. We can do this while still being in the Log Analytics query pane:

Click on the 3 dots and then on “+ New alert rule”. This creates an alert rule completely based on the query we have used.
On this page, scroll down to “Alert logic” and set the following settings:
- Operator: Greater than or equal to
- Threshold value: 1
- Frequency of evaluation: 5 minutes

This means the alert is triggered if the query finds 1 or more successful attempts. You can customize this is needed.
Now go to the “Actions” tab. We now need to create an Action group, where we define what kind of notification to receive.
Create a action group if you don’t already have one.

Give it a name and displayname. Good practice is to use a different action group for this alert, as you can define per action group what kind of notification and receivers you want to use.
Now go to the “Notifications” tab. Select “Email/SMS message/Push/Voice” and configure the alert. This is pretty straight forward.
I have configured Microsoft to call me when this alert is triggered:

Advance to the next tab.

You could also run an automated action against this trigger. As this includes Webhook, you could get customized messages for example on your Microsoft Teams account.
Finish the creation of the Action group.
Step 5: Let’s test the solution
Now we have configured everything, we can test the working of this alert. Let’s prepare an InPrivate window to login to the account:
I have logged in seconds from 13:20:08 hours. Let’s wait till I receive the alerting phone call.
And at 13:27, 7 minutes later, I got an call from Microsoft that the alert was triggered:

This way we will know in a very direct way our break glass account is possibly misused. We could also choose to only get messages from this or use the webhook option which will be less rigorous than getting a phone call. But hey, at least the option exists.
Summary
Monitoring the use of your Break Glass Admins is very important. Those accounts should be a last resort of managing Azure when nothing else and personal accounts doesn’t work. They should be tested at least twice a year and good monitoring like this on the accounts is preferred.
Thank you for reading this post and I hope it was helpful.
Sources
These sources helped me by writing and research for this post;
- https://azure.microsoft.com/en-us/pricing/details/monitor/
- https://learn.microsoft.com/en-us/entra/identity/monitoring-health/howto-analyze-activity-logs-log-analytics
Β
End of the page π
You have reached the end of the page. You can navigate through other blog posts as well, share this post on X, LinkedIn and Reddit or return to the blog posts collection page. Thank you for visiting this post.
If you think something is wrong with this post or you want to know more, you can send me a message to one of my social profiles at: https://justinverstijnen.nl/about/
If you find this page and blog very useful and you want to leave a donation, you can use the button below to buy me a beer. Hosting and maintaining a website takes a lot of time and money. Thank you in advance and cheers :)
The terms and conditions apply to this post.
How to properly secure Break Glass Accounts in your Entra ID
In our environment, we will do everything to secure it as much as possible. We give users only the permissions they need and only at given times, we enable Conditional Access to limit access to our data as much as possible.
But we also create Break Glass administrator accounts as our last resort, a method to login if everything else doesn’t work. Security wise, this sounds against all rules but we prefer a account to login in emergency situations over a complete tenant lockout.
To help you secure break glass administrator accounts, I have 10 generic industry-known advices for these accounts which you can implement relatively easy. These help you on top of all other security mechanisms (CA/MFA/PIM/Least privilege) securing, decreasing the chance of lockouts and decrease the value for possible attackers.
List of recommendations
The list of recommendations which I will describe further:
- Have at least 2 accounts
- Have the accounts cloud only -> not synced from Active Directory
- Use the .onmicrosoft.com domain and no license
- Exclude from all Conditional Access policies
- Do not use licenses on Administrator accounts
- Passwords must be at least 64 and max 256 characters
- Avoid “break glass admin” or any tip to a high privileged account
- Register FIDO2 key for the account
- Setup Monitoring for login alerts
- Test the accounts twice per year
1: Have at least 2 accounts with Global Administrator permissions
Very important to have at least 2 accounts (with a maximum of 4) with Global Administrator permissions. Most of the time, we will limit the amount of privileges but we need to have at least 2 accounts with those permissions.
- If one of the accounts won’t work, the other mostly will
2: Use cloud only accounts
For administrator accounts, it is recommended to use cloud only accounts. This way, any compomise in local or cloud accounts doesn’t mean the attack flows into the other direction.
If attackers manage to break into a active directory account, they will also get into your cloud environment which we want to limit.
3: Use .onmicrosoft.com domain only
For administrator accounts, and especially break glass administrator accounts, it is recommended to only use the .onmicrosoft.com domain. This domain is the ultimate fallback if something happens to your domain, or someone managed to make a (big) mistake in the DNS records. It can happen that user accounts fall back to the .onmicrosoft.com domain.
I have seen this happening in production, and so using the .onmicrosoft.com domain helps you gaining quicker access in case of emergency.
4: Exclude Break Glass administrator accounts from Conditional Access
To ensure Break Glass administrators are always permitted to login, ensure they are excluded from all blocking conditional access policies. If you make a sudden mistake in obe of the policies, and your Break glass administrator is included, there is no way to sign in anymore, and you’ll be lcoked out.
5: Do not use licenses on Administrator accounts
Do not use licenses on Administrator accounts. Using licenses potentially make them a bigger target in recoinassance stages of an attack, they are easier to find and the licenses expose services of M365 further.
6: Use strong and big passwords
A great recommendation is to use long and strong passwords. Strong passwords consists of all 4 possible character types:
- Lowercase characters
- Uppercase characters
- Numbers
- Special characters
Use anywhere between 64 and 256 characters passwords for break glass administrator accounts. Save those in a safe place like an encrypted password storage.
Tip: use my Password generator for generatng passwords: https://password.jvapp.nl/
7: Ensure proper naming
We have to name our break glass administrators well. During breaches, attackers will search for possible high-value targets to shift their attack to.
- Avoid terms like “admin”, “breakglass” or “emergency”, the attacker will instantly know where their gold is at
A good advice is to name break glass accounts to a person, a product you and your company likes or to a movie. Let you creativity be king on this one.
8: Register FIDO2 key for break glass adminstrators
You can also register FIDO2 keys for break glass administrators. These are a hardware key used as second factor which we can put in a safe or store somewhere else really safe. It must also be audited if anyone in the company gains access to the security key so everyone knows who, when and why it was last used.
9: Setup monitoring alerts for Break Glass administrators
As we don’t want break glass administrator accounts to be used on a daily basis and being actively attacked, you might want to setup alerts for people logging in to the account.
To setup notifications like phone calls, I have this guide for you: https://justinverstijnen.nl/get-notifications-when-entra-id-break-glass-admins-are-used
10: Test Break Glass administrator accounts twice per year
We create the break glass administrator accounts, but mostly never test them properly. It is important to test break glass accounts at least twice per year, and know exactly if they work properly and the correct roles and permissions are active.
To test this, login to the account and check if you still have the correct roles and that they are “Active”, instead of the PIM “Eligible”.
Summary
It is really important to have back-up/break glass accounts available in your environment. You’ll never know when someone makes a mistake or a account doesn’t work because of some outage or other problem. Maybe your account is brute-forced and locked out for 30 minutes.
I hope this guide was helpful and thank you for reading.
Sources
These sources helped me by writing and research for this post;
Β
End of the page π
You have reached the end of the page. You can navigate through other blog posts as well, share this post on X, LinkedIn and Reddit or return to the blog posts collection page. Thank you for visiting this post.
If you think something is wrong with this post or you want to know more, you can send me a message to one of my social profiles at: https://justinverstijnen.nl/about/
If you find this page and blog very useful and you want to leave a donation, you can use the button below to buy me a beer. Hosting and maintaining a website takes a lot of time and money. Thank you in advance and cheers :)
The terms and conditions apply to this post.
Solved - ADSync service stopped (Entra Connect Sync)
Sometimes, the ADSync service stops without further notice. You will see that the service has been stopped in the Services panel:

In this guide I will explain how I solved this problem using a simple PowerShell script.
The Check ADSync script
The PowerShell script that fixes this problem is on my GitHub page:
The script simply checks if the service is running, if this is the case the script will be terminated. If the service is not running, the service will be started.
The problem and possible causes
The problem is caused after a server restart, then the service will not start itself automatically, even when this is selected in Windows. This is enabled by defaut by the installation wizard.
In the Event Log there will be these events:
- Event 7000: The Microsoft Azure AD Sync service failed to start due to the following error: The service did not start due to a logon failure.
- Event 7031: The Microsoft Azure AD Sync service terminated unexpectedly. It has done this 1 time(s). The following corrective action will be taken in 0 milliseconds: Restart the service.
The fun part is that it cannot login according to the Entra Connect Sync tool but after some minutes it does.
Running the script
We can run the script manually using the PowerShell ISE application.

After running the script, the service does run:

Installing the clean script automatically
For installation with Task Scheduler I included an installation script that, by default, configures a task in the Windows Task Scheduler that runs it;
- Every first day of the month
- At hour 03:00
If these settings are great for you, you can leave them as-is.
The Installation script creates a folder in C:\ named “Scripts” if not already there and places the cleaning script there.
Installation
Click on the blue button above. You now are on the Github page of the script.

Click on “Code” and then “Download ZIP”.
Then place the files on the server where you want to install the script.

Open Powershell ISE as administrator.
Now open the “Install” script.

Review it’s default settings and if you feel at home in PowerShell, review the rest of the script to understand what it does.

You can change the schedule very easily by changing the runtime: 0:00 till 23:59 and the day of month to specify the day number of the month (1-31).
After your schedule is ready, let’s ensure we temporarily bypass the Execution Policy by typing the command in the blue window below:
Set-ExecutionPolicy Unrestricted -Scope Process -ForceThis way the execution policy stays enabled but for this session only it’s been lowered. When you close the window, you have to type this again before be able to run scripts.
Execute the command, and when prompted to lower the policy, click Yes.
Now execute the Install script by clicking the green “Run” button:

After executing the script, we get the message that the task has been created succesfully:

Let’s check this in the Windows Task Scheduler:

As you can see, the script is succesfully installed to Task Scheduler. This ensures it runs every first of the month at 03:00 (or at your own defined schedule). Also, the script has been placed in C:\Scripts for a good overview of the scripts of the system.
Summary
This simple script resolved me a lot of problems, checking the service automatically and starting it. A Entra Connect Sync not running is very stable. Users can get different types of errors, de-synchronisations and passwords that are not working.
Thank you for visiting this page and I hope it was helpful.
Sources
These sources helped me by writing and research for this post;
- None
Β
End of the page π
You have reached the end of the page. You can navigate through other blog posts as well, share this post on X, LinkedIn and Reddit or return to the blog posts collection page. Thank you for visiting this post.
If you think something is wrong with this post or you want to know more, you can send me a message to one of my social profiles at: https://justinverstijnen.nl/about/
If you find this page and blog very useful and you want to leave a donation, you can use the button below to buy me a beer. Hosting and maintaining a website takes a lot of time and money. Thank you in advance and cheers :)
The terms and conditions apply to this post.
Match AD users using Entra Connect Sync and MSGraph
Sometimes, it is necessary to match an existing local Active Directory (AD) user through Entra Connect with an existing Entra ID user (formerly known as Azure AD). This process ensures that the account in both environments is aligned and maintains the same underlying configurations and settings across systems.

What is soft-matching?
Most of the time the system itself will match the users automatically using soft-matching. Here the service will be matching users in both Entra ID and Active Directory by using known attributes like UserPrincipalName and ProxyAddresses.
What is hard-matching?
In some cases, especially when you use different Active Directory and Entra ID domains, we need to give the final tip to match the users. We will tell Entra ID what the GUID of the on-premises user is by getting that value and encode it into Base64. Then we pass Entra ID this value so it understands what local user to link with what cloud user. This process is called “hard-matching”.
The process described
The steps to hard-match an Entra ID and Active Directory user are in short:
- Determine the local and cloud user you want to match
- On the on-premises Active Directory, run the command “Get-ADUser *username*”
- Copy the GUID value
- Run the command “[Convert]::ToBase64String([guid]::New(”*GUID*").ToByteArray())" with *GUID* replaced by the GUID from step 3
- Copy the Base64 value
- Connect to Microsoft 365 by using “Connect-MSOLService”
- Run the command “Set-MsolUser -UserPrincipalName user@domain.com -ImmutableId *BASE64*
- Run a Entra Connect Sync
Step 1: Fetching Active Directory GUID
To merge an existing on-premises user and an existing cloud user into one unified user account under the hood, follow these steps:
Log in to your Active Directory management server
Open PowerShell.
Execute the following command:
Get-ADUser -Identity *username*Replace *username* by the username of the user you want to match.
The output of the command above will be something like this:
DistinguishedName : CN=administrator,OU=Users,DC=justinverstijnen,DC=nl
Enabled : True
GivenName : Administrator
Name : administrator
ObjectClass : user
ObjectGUID : c97a6c98-ded8-472c-bfb6-87ed37d324f5
SamAccountName : administrator
SID : S-1-5-21-1534517208-3616448293-1356502261-1244
Surname : Administrator
UserPrincipalName : administrator@justinverstijnen.nlCopy the value of the ObjectGUID, in this case:
c97a6c98-ded8-472c-bfb6-87ed37d324f5Because Active Directory uses GUID for a unique identifier of the user and Entra ID uses a Base64 value for a unique identifier, we need to convert the GUID string to a Base64 string. We can do this very easy with Powershell too:
[Convert]::ToBase64String([guid]::New("c97a6c98-ded8-472c-bfb6-87ed37d324f5").ToByteArray())We get a value like this:
mGx6ydjeLEe/toftN9Mk9Q==Now we have the identifier Entra ID needs. We change the ID of the cloud user to this value. This way the system knows which on-premises user to sync with which cloud user.
Step 2: Logging into Entra ID with Microsoft Graph
To actually match the users, we need to login to Microsoft Graph in PowerShell, as we can there perform the actions. For installation instructions of the Microsoft Graph PowerShell module: https://www.powershellgallery.com/packages/Microsoft.Graph/2.24.0
Run the following command to login to Microsoft Entra ID with Microsoft Graph:
Connect-MgGraph -Scopes "User.ReadWrite.All"Login with your Microsoft Entra ID administrator account.
Step 3: Set the new Immutable ID in Microsoft Entra
After succesfully logging into Microsoft Graph, run the command to set a (new) Immutable ID for your cloud user:
Update-MgUser -UserId "administrator@justinverstijnen.nl" -OnPremisesImmutableId "mGx6ydjeLEe/toftN9Mk9Q=="Now the user is hard matched. You need to run a Entra Connect synchronization to finish the process.
Log in to the server with AD Connect/Entra Connect sync installed and run the command:
Start-ADSyncSyncCycle -PolicyType DeltaNow your on-premises user and cloud user have been matched!
Summary
Hardmatching users is relatively easy, but requires some steps that are good to know. After doing this around 3 times you will perform this completely on “auto-pilot”.
Sources
These sources helped me by writing and research for this post;
Β
End of the page π
You have reached the end of the page. You can navigate through other blog posts as well, share this post on X, LinkedIn and Reddit or return to the blog posts collection page. Thank you for visiting this post.
If you think something is wrong with this post or you want to know more, you can send me a message to one of my social profiles at: https://justinverstijnen.nl/about/
If you find this page and blog very useful and you want to leave a donation, you can use the button below to buy me a beer. Hosting and maintaining a website takes a lot of time and money. Thank you in advance and cheers :)
The terms and conditions apply to this post.
Implement Certificate-based authentication for Entra ID scripts
When using Entra ID, we can automate a lot of different tasks. We can use a script processing server for this task but doing that normally means we have to save credentials or secrets in our scripts. Something we don’t want.
Today I will show how to implement certificate-based authentication for App Registrations instead of using a client secret (which still feels like a password).
Requirements
- Around 20 minutes of your time
- An Entra ID environment if you want to test this
- A prepared Entra ID app registration
- A server or workstation running Windows to do the connection to Entra ID
- Some basic knowledge about Entra ID and certificates
How does these certificates work?
Certificate based authentication means that we can authenticate ourselves to Entra ID using a certificate instead of user credentials or a password in plain text. When using some automated scripts it needs permissions to perform its actions but this means storing some sort of authentication. We don’t want to store our credentials on the server as this decreases our security and a potential risk of compromise.
Certificate based authentication works by generating a certificate (SSL/Self-signed) and using that for authentication. The certificate has to be enabled and on both sides, like described in the picture above.
This means that if an client doesn’t have a allowed certificate installed, we can never connect. This is great, so we can store our certificates in a digital safe and only install this on our script processing server. When generating a self signed certificate, a private key is also generated by the computer which means this also has to be in hands of an attacker to abuse your certificate.
After authenticating, we have the permissions (API or Entra Roles) assigned to the Enterprise Application/App Registration, which we will call a “Service Principal”.
Note: Self Signed certificaties will expire after 365 days (1 year).
Why this is more safe than secrets/credentials?
In the old Windows Server days, we could sometimes find really unsecure jokes like these:

This is something that is really unsecure and I advice you to never do actions like these. With certificate-based authentication we eliminate the need for this by a lot.
Generating a self signed certificate
On our server or workstation where you want to setup the connection, we can generate a self signed certificate. The server then generates a certificate which is unique and can be used for the connection.
Let’s open PowerShell to generate a new Self Signed certificate. Make sure to change the *certificatename to your own value:
New-SelfSignedCertificate -Subject *certificatename* -CertStoreLocation Cert:\CurrentUser\MyThen we have to get the certificate to prepare it for exporting:
$Cert = Get-ChildItem -Path Cert:\CurrentUser\My | Where-Object {$_.Subject -eq "CN=*certificatename*"}Then give your certificate a name:
$CertCerPath = "Certificate.cer"And then export it to a file using the settings we did above:
Export-Certificate -Cert $Cert -FilePath $CertCerPath -Type CERTWe now have generated a self signed certificate using the settings of the server. We now must import this into Entra ID. This file doesn’t include a private key and this is stored on the server.
Adding a certificate to a Entra ID app registration
Now head to the Entra ID portal and go to your already created App registration, and then to “Certificates & Secrets”.

Upload the .cer file there to assign it to the app registration and get the assigned roles.
Now you will see the certificate uploaded:

Now we have the thumbprint of the certificate, which is a identifier of the certificate. You can also get this on the server where you just generated the certificate:
$cert.ThumbprintConnecting to Entra ID using a certificate
Installing the Microsoft Graph Powershell module can be done with:
PowerShell
Install-Module Microsoft.Graph -Scope CurrentUser -Repository PSGallery -Force
We can now logon to Microsoft Graph using this certificate, we must first fill in the parameters on your server:
$clientId = "your client-id"
$tenantId = "your tenant-id"
$thumbprint = "your thumbprint"
$cert = Get-ChildItem -Path Cert:\CurrentUser\My | Where-Object { $_.Thumbprint -eq $thumbprint }Make sure you use your own client ID, Tenant ID and certificate thumbprint.
Now let’s connect to Graph with your certificate and settings:
Connect-MgGraph `
-ClientId $clientId `
-TenantId $tenantId `
-Certificate $certNow you should be logged in succesfully:

I double checked if we were able to get our organization and that was the case. This is a command that doesn’t work when not connected.
Connecting to Entra ID without a certificate (test)
As we should not be able to connect without the certificate installed, we will test this for sure on another device:

Powershell cannot find our certificate in the store. This is as expected as we didn’t install it. But let’s try another method:

With Exchange Online Powershell, this also doesn’t work because we don’t have the certificate installed. Working as intended!
Summary
Implementing Certificate based authentication is a must for unattended access to Entra ID and app registrations. Its a great authentication method when having a script processing server that needs access to Entra ID or any Microsoft 365/Azure service and not wanting to hard-code credentials which you shouldn’t do either.
This can also be used with 3rd party applications when supported. Most of the applications will only support Client ID and secrets, as this is much easier to implement.
Sources
These sources helped me by writing and research for this post;
- Create a self-signed public certificate to authenticate your application - Microsoft identity platform | Microsoft Learn
- Install the Microsoft Graph PowerShell SDK | Microsoft Learn
Β
End of the page π
You have reached the end of the page. You can navigate through other blog posts as well, share this post on X, LinkedIn and Reddit or return to the blog posts collection page. Thank you for visiting this post.
If you think something is wrong with this post or you want to know more, you can send me a message to one of my social profiles at: https://justinverstijnen.nl/about/
If you find this page and blog very useful and you want to leave a donation, you can use the button below to buy me a beer. Hosting and maintaining a website takes a lot of time and money. Thank you in advance and cheers :)
The terms and conditions apply to this post.
Audit your Entra ID user role assignments
Today I have a relatively short blog post. I have created a script that exports all Entra ID user role assignments with Microsoft Graph. This can come in handy when auditing your users, but then realizing the portals doesn’t always show you the information in the most efficient way.
Therefore, I have created a script that only gets all Entra ID role assignments to users of every role and exports it to a nice and readable CSV file.
Requirements
- Microsoft Graph PowerShell module
- Entra P2 or Governance license for PIM
- Only required for fetching PIM specific data. Script can run without licenses.
Entra ID User role assignments script
To start off with the fast pass, my script can be downloaded here from my Github page:
Using the Entra ID User role assignments script
I have already downloaded the script, and have it ready to execute:

When executed, it asks to login to a tenant. Here you have to login to the tenant you want to audit. After that it will be performing the checks. This can take a while with several users and role assignments.
When prompted that the Execution Policy is restricted, you can use this command for a one-time bypass (till the window closes):
PowerShell
Set-ExecutionPolicy Unrestricted -Scope Process
After the script finishes all the checks, it puts out a CSV file in the same folder as the script which we can now open to review all the Entra ID user role assignments:

As you can see, this shows crystal clear what users and assigned roles this environment has.
Using the script without PIM licenses
If your environment doesn’t have any licenses for Privileged Identity Management (PIM), we can still use the script, but an error will be printed in the processing of the script:
β οΈ Eligible (PIM) role assignments could not be retrieved.
Microsoft Entra ID P2 or Governance license is required. Script will continue to fetch the rest...Summary
This very short blog post shows the capabilities of this users script. In my opnion, the GUI shows most of the information, but is not particularly good at summarizing information from multiple pages. Powershell is, as we can get information from everywhere and put it in one single file.
Sources
These sources helped me by writing and research for this post;
I hope my script is useful and thank you for reading.
Β
End of the page π
You have reached the end of the page. You can navigate through other blog posts as well, share this post on X, LinkedIn and Reddit or return to the blog posts collection page. Thank you for visiting this post.
If you think something is wrong with this post or you want to know more, you can send me a message to one of my social profiles at: https://justinverstijnen.nl/about/
If you find this page and blog very useful and you want to leave a donation, you can use the button below to buy me a beer. Hosting and maintaining a website takes a lot of time and money. Thank you in advance and cheers :)
The terms and conditions apply to this post.
Audit your privileged Entra ID applications
In Microsoft Entra ID it’s possible to create App registrations and Enterprise applications who can get high privileges if not managed and monitored regularly. We do our best with Identities to be secure, with security processes like MFA, access reviews and such, but most of the companies don’t care that much about the Enterprise applications.
In this post, I will try to convince you that this is as much as important as identities. For helping you to solve this I built a PowerShell script to get a complete overview of all the applications and their permissions.
Entra ID Privileged Applications report script
To start off with the fast pass, my script can be downloaded here from my Github page:
This script can be used to get a report of all high privileged applications across the tenant. Go to this section for instructions of how to use the script and the output.
What are Enterprise Applications?
Enterprise Applications in Entra ID are the applications which will be registered when users need them. Somethimes, it can be for a add-on of Outlook or Teams, but other times this can be to enable Single Sign On to 3rd party applications.
In terms of Entra ID and Identity, we call a Enterprise Application a “Service Principal”. A principal for a service to give permissions to.
Enterprise applications are mostly pre-configured by the 3rd party publisher of the application that needs permission. However, a user can be prompted to give their information to a application. This looks like this:

As we can see, the application gets the information of the calendars, the profile of the user and gets data. These alone aren’t not that much privileged, but this can be much worse. Let’s take a look at “App Registrations”.
What are App Registrations?
App Registrations are applications who are mostly custom. These can be used for Single Sign On integration with 3rd party applications or to provide access from another application to Microsoft Entra ID and subservices.
App Registrations are commonly more privileged and can be dangerously high privileged, even not having a requirement for MFA. The only thing you need to use an app registration is:
- Client ID
- Tenant ID (public available: https://tenantlookup.jvapp.nl)
- Secret/Certificate
App registrations can have permissions far above “Global Administrator”, but we don’t handle them like global administrators or even higher accounts. The Microsoft Secure Score also doesn’t report them and they can be hard to find.
These applications are used in practice by hackers to leave backdoors in tenants to remain in the tenant. If they do this right, they can be unseen for months while still stealing company information.
What to do to prevent unauthorized access through apps?
We can do several things to avoid being hacked by this sort of things:
- Audit all applications every X days, deleting apps that aren’t needed
- You can use my script to help you audit
- Saving App registration information in safe places only, don’t transfer them in plain-text over email
- Treat these applications as passwords and certificates
Let’s create a High privileged App registration
We will now create a high privileged app registration, purely to showcase the permissions and to show you how much of a deal this could be.
Open the Microsoft Entra admin center and go to: Applications -> App registrations
Click on “+ New registration”:

Fill in a name and the rest doesn’t care for testing purposes. You can leave them default.

Click Register.
Permissions and Assignment
Now the application is created. Open it if not already redirected. Write down the “Client ID” and the “Tenant ID” because we will need them in a short moment. Then go to the section “API permissions”.

Here you find all assigned permissions to the application. Click on “+ Add a permission” to add permissions to this application. Then click on “Microsoft Graph”.

Microsoft Graph is the new API of Microsoft that spans across most of the Microsoft Online services.
Then click on “Application permissions”:

Now we can choose several permissions that the application gets. You can search for some of the High privileged apps, for example these:
| Permission name | Action |
|---|---|
| Directory.ReadWrite.All | Read and write directory data |
| User.ReadWrite.All | Read and write all users’ full profiles |
| Policy.ReadWrite.ConditionalAccess | Read and write your organization’s conditional access policies |
| Mail.ReadWrite | Read and write mail in all mailboxes |
| Application.ReadWrite.All | Read and write all applications |
| PrivilegedAccess.ReadWrite.AzureResources | Read and write privileged access to Azure resources |
As you can see; if I create the application with these permissions I have a non-monitored account which can perform the same tasks as a Global Administrator, disabling MFA, exporting all users, reading contents of all mailboxes, creating new backdoors with applications and even escalate privileges to Azure resources.
Create the application with your permissions and click on “Grant admin consent for ‘Tenant’” to make the permissions active.

Create Client secret for application
We can now create a Client secret for this application. This is a sort of master password for accessing the service principal. This can also be done with certificates, which is more preferred in practice environments, but it works for the demo.
In Entra, go to the application again, and the to “Certificates & secrets”:

Create a new secret.

Specify the period and the lifetime and click on “Add” to create the secret.

Now copy both the Value, which is the secret itself and the Secret ID and store them in a safe place, like a password manager. These can be viewed for some minutes and then will be concealed forever.
Using this application to login on Microsoft Graph
We can now use the application to login to Microsoft Graph with the following script:
Refer to my GitHub page for the requirements for using the script and Microsoft Graph.
# Fill in these 3 values
$ApplicationClientId = '<your-app-client-id>'
$TenantId = '<your-tenant-id>'
$ApplicationClientSecret = '<your-client-secret>'
Import-Module Microsoft.Graph.Authentication
# Create a ClientSecretCredential object
$ClientSecretCredential = [Microsoft.Graph.Auth.ClientCredentialProviderFactory]::CreateClientSecretCredential(
$TenantId,
$ApplicationClientId,
$ApplicationClientSecret
)
# Connect to Microsoft Graph without the welcome banner
Connect-MgGraph -ClientSecretCredential $ClientSecretCredential -NoWelcomeHere we can fill in the Client ID and Tenant ID from the previous steps and the Secret from the created client secret. Then run it with PowerShell. I advice to use the Windows PowerShell ISE for quick editing of the script and executing + status for debugging.
After logging in we can try to get and change information:
Get all Users:
Get-MgUserCreate user:
$PasswordProfile = @{
Password = 'Pa$$w)rd!'
}
New-MgUser -Displayname "Test" -MailNickname "test" -Userprincipalname "test@justinverstijnen.nl" -AccountEnabled -PasswordProfile $PasswordProfileRemove user:
Remove-MgUser -UserId "247f8ec8-c2fc-44a0-9665-48b85c19ada4" -ConfirmWatch the demo video here:
Now a user isn’t that destructive, but given the scopes we assigned: we can do a lot more. For more Microsoft Graph commands, visit: https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.users/?view=graph-powershell-1.0
Using my script to Audit all high privileged applications
Now that we have created and abused our demo application, let’s use my script to get a report where this application must be reported.
You can, once again, download the script here:
I have already downloaded the script, and have it ready to execute:

When executed, it asks to login to a tenant. Here you have to login to the tenant you want to audit. After that it will be performing the checks. This can take a while with several applications.
When prompted that the Execution Policy is restricted, you can use this command for a one-time bypass until the window closes:
<div class="td-card card border me-4">
Set-ExecutionPolicy Unrestricted -Scope ProcessAfter the script finishes all the checks, it puts out a CSV file in the same folder as the script which we can now open to review the applications and their permissions:

As we can see, this must be a far too much privileged application, and everything must be done to secure it:

It also queries if the applications has active secrets or certificates:

So this way we know within minutes which applications we must monitor and even deleted or seperated into more, smaller, less privileged applications.
Summary
I hope I convinced you with this guide how much of an risk the applications in Microsoft Entra ID really can be. They can be used by threat actors, as Break glass application or by attackers to leave backdoors in a tenant after a breach.
Sources
These sources helped me by writing and research for this post:
- https://learn.microsoft.com/en-us/entra/identity-platform/application-consent-experience
- https://learn.microsoft.com/en-us/graph/permissions-overview?tabs=http#comparison-of-delegated-and-application-permissions
- https://learn.microsoft.com/en-us/powershell/microsoftgraph/authentication-commands?view=graph-powershell-1.0#use-client-secret-credentials
- https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.users/?view=graph-powershell-1.0
I hope I informed you well with this post and thank you for reading. I also hope my PowerShell script comes in very handy, because I couldn’t find a good one working online.
Β
End of the page π
You have reached the end of the page. You can navigate through other blog posts as well, share this post on X, LinkedIn and Reddit or return to the blog posts collection page. Thank you for visiting this post.
If you think something is wrong with this post or you want to know more, you can send me a message to one of my social profiles at: https://justinverstijnen.nl/about/
If you find this page and blog very useful and you want to leave a donation, you can use the button below to buy me a beer. Hosting and maintaining a website takes a lot of time and money. Thank you in advance and cheers :)
The terms and conditions apply to this post.





