Category Archives: EntraID

Categorizing Service Principals in Entra

For M365Permissions I wanted to categorize service principals in an actually useful way.

This is what I came up with so far

    function get-servicePrincipalType{
        Param(
            [Parameter(Mandatory=$true)][object]$spn
        )

        #managed identities are simple :)
        if($spn.servicePrincipalType -eq "ManagedIdentity"){
            return "ManagedIdentity"
        }        

        #other SPN's can be hosted by us, by Microsoft or by a third party 
        #Although 9188040d-6c67-4c5b-b112-36a304b66dad is also officially Msft, it contains consumer apps not built or vetted by Microsoft thus we treat it as third party
        if($spn.appOwnerOrganizationId -in ("f8cdef31-a31e-4b4a-93e4-5f571e91255a","72f988bf-86f1-41af-91ab-2d7cd011db47","7579c9b7-9fa5-4860-b7ac-742d42053c54")){
            return "MicrosoftApplication"
        }elseif($spn.appOwnerOrganizationId -eq <YOURTENANTID>){
            #this is either a homebrew app or an AI agentic app
            if($spn.tags -and ($spn.tags -contains "AgenticApp" -or $spn.tags -contains "AIAgentBuilder")){
                return "AiAgent"
            }else{
                return "InHouseApplication"
            }
        }else{
            return "ThirdPartyApplication"
        }              
    }      

Function to Spot ALL All-User and All-Guest Groups in Entra ID

There are probably many scenario’s where you’d like to identify which Entra groups contain ‘all users’, ‘all guests’ or a combination (all members+all guests).

In my case, I want to use this in M365Permissions, but also needed it for a Maester test to be more precise. It had to be language and implementation agnostic.

M365Permissions uses this mainly for reports that look at oversharing (e.g. when securing a tenant or implementing copilot). But this could also be useful for red/blue teams or any other tenant analysis tooling.

In M365Permissions, I initially looked at the dynamic rule itself, but this is unreliable. Dynamic rules can contain many additional components and can be ordered or written in many ways or the group may have been created without a dynamic rule through e.g. automation.

So I decided to use another approach!

Just get all tenant users from Graph (counts per type).

Then for a given group, look if it matches one of those counts and return a type. Of course, casting members to users to avoid counting devices and looking up membership recursively 🙂

Function: https://github.com/jflieben/assortedFunctionsV2/blob/main/Get-EntraDynamicGroupType.ps1

Scanning unattended using a Service Principal

If you want to use the M365Permissions module in unattended (or headless) mode, e.g. from a runbook or on a server as scheduled task, you’ll need to create an app registration in Entra with sufficient permissions to scan your tenant.

Setup instructions (automated)

  1. Load the module using Import-Module -Name M365Permissions
  2. Create a service principal using Set-ScanPermissions -switchToSPNAuth -appName "M365Permissions (AppOnly)"
  3. Run Connect-M365 -ServicePrincipal
  4. Start a scan (e.g. using get-allM365Permissions)
  5. Scroll down if you also want to scan PowerBI

Setup instructions (manual)

  1. Go to https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/CreateApplicationBlade/quickStartType~/null/isMSAApp~/false
  2. Decide on a name and click Register
  3. Go to API permissions and enter as follows:
  1. Don’t forget to click ‘Grant admin consent’
  2. Note down the ‘Application (client) id’ and ‘Directory (tenant) id’ from the ‘Overview’ page
  3. run the new-SpnAuthCert command from the M365Permissions module, it will output a .cer file. Make sure to use the tenant ID from step 5.
  4. The PFX file has to be imported on any machine you wish to run the module on, except for the machine where you ran the new-SpnAuthCert command.
  5. Go to ‘Certificates & secrets’ and upload the .cer file
  1. Go to the Roles and Administrators in Entra and select the Global Administrator role.
  2. Add the new app registration to the global administrator role:
  1. Run set-M365PermissionsConfig -LCTenantId <tenant ID> -LCClientId <client id> with the values from step 5 to configure the module to use your new SPN to log in.
  2. Alternatively, you can configure the LCTENANTID and LCCLIENTID environment variables with above information.
  3. If you also configure the LCAUTHMODE environment variable with a value of “ServicePrincipal”, the module will log in to your tenant fully automatically the moment it is imported.
  4. If you’re running interactively, you can now use connect-M365 -ServicePrincipal before running a scan to use the SPN instead of delegated authentication

Scanning PowerBI

If you also want to include PowerBI in your scans, you’ll have to authorize the service principal.

PFX certificate location

If you want to run from an automation account, Azure function etc, for now you’ll have to retrieve the .pfx file dynamically and install it before the module loads because the module looks in the local certificate store for a certificate with your tenant ID as subject.

I will consider adding support for Managed Identities in the future to make this simpler, and possibly also add keyvault integration or direct path configuration an option.

Restrictions

When scanning as service principal, you cannot scan:

  • Graph Subscriptions
  • PowerBI Gateways

You’ll see a warning in the logs about this as they’ll automatically be excluded.

Setup instructions (automated)

to be added in a future version

M365Permissions Module

Let’s be honest, the TeamPermissions module ‘s name has quickly lost touch with what it does (already doing Sharepoint and Onedrive as well).

Adding the overwhelming number of positive reactions and rapid adoption, I want to add even more features:

  1. Scanning EntraID roles
  2. Scanning Exchange roles
  3. Scanning Mailbox permissions
  4. Change detection (between scans)
  5. Scanning Azure RM roles
  6. Scanning PowerBI roles
  7. SPN based scanning

So I’ve decided to rename it to M365Permissions!

Obviously it’ll take a lot of time/work to get above coded up and tested.

But for now I can already give you the M365Permissions PowerShell module, which includes:

  • EntraID roles (permanent and eligible)
  • Lots of bug fixes
  • Performance improvements (especially with lots of small sites)
  • Everything the TeamPermissions module did

Please give it a spin and let me know what other features you’d like to see!

Other links:

M365Permissions in the PSGallery

M365Permissions on Github