Back to Checks
m365

Administrative user has no license or an allowed license (AAD_PREMIUM or AAD_PREMIUM_P2)

admincenter_users_admins_reduced_license_footprint
Service: admincenterSeverity: high
OfficialBuilt-inVerified
Categories:identity-accesse3
Resource Type:NotDefined

Privileged users in Microsoft 365 are evaluated for a reduced license footprint: only AAD_PREMIUM (P1) or AAD_PREMIUM_P2 (P2), or no license. Assignments that include productivity app suites indicate excess application entitlements on administrative accounts.

Risk

Productivity licenses on privileged identities create mailboxes and collaboration surfaces that widen attack paths. Phishing, malicious content, or rogue OAuth apps can steal credentials/tokens, enabling tenant-wide role misuse, data exfiltration, and configuration tampering-compromising confidentiality and integrity.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler m365 --checks admincenter_users_admins_reduced_license_footprint

Recommendation

Maintain dedicated admin accounts with a least-privilege, reduced-license model: assign only Microsoft Entra P1/P2 features needed for identity security, or keep them unlicensed for apps. Separate admin from daily-use accounts, enforce MFA and just-in-time elevation, and use privileged access workstations for administration.

Remediation

CLI

Set-MgUserLicense -UserId <USER_PRINCIPAL_NAME_OR_ID> -AddLicenses @() -RemoveLicenses @(Get-MgUserLicenseDetail -UserId <USER_PRINCIPAL_NAME_OR_ID> | Select-Object -ExpandProperty SkuId)

Other

1Sign in to https://admin.microsoft.com
2Go to Users > Active users
3Select the affected administrative user
4Open Licenses and apps
5To pass the check, do ONE of the following:
6- Unassign all licenses (make the user unlicensed); or
7- Assign only Microsoft Entra ID P1 or P2 and remove all other licenses
8Click Save changes

Check Code

from typing import List

from prowler.lib.check.models import Check, CheckReportM365
from prowler.providers.m365.services.admincenter.admincenter_client import (
    admincenter_client,
)


class admincenter_users_admins_reduced_license_footprint(Check):
    """Check if users with administrative roles have a reduced license footprint.

    This check ensures that users with administrative roles (like Global Administrator)
    have valid licenses, specifically one of the allowed licenses. If a user with
    administrative roles has an invalid license, the check fails.

    Attributes:
        metadata: Metadata associated with the check (inherited from Check).
    """

    def execute(self) -> List[CheckReportM365]:
        """Execute the check for users with administrative roles and their licenses.

        This method iterates over all users and checks if those with administrative roles
        have an allowed license. If a user has a valid license (AAD_PREMIUM or AAD_PREMIUM_P2) or no license,
        the check passes; otherwise, it fails.

        Returns:
            List[CheckReportM365]: A list containing the result of the check for each user.
        """
        findings = []
        allowed_licenses = ["AAD_PREMIUM", "AAD_PREMIUM_P2"]
        for user in admincenter_client.users.values():
            admin_roles = ", ".join(
                [
                    role
                    for role in user.directory_roles
                    if "Administrator" in role or "Global Reader" in role
                ]
            )

            if admin_roles:
                report = CheckReportM365(
                    metadata=self.metadata(),
                    resource=user,
                    resource_name=user.name,
                    resource_id=user.id,
                )
                report.status = "PASS"
                report.status_extended = f"User {user.name} has administrative roles {admin_roles} and does not have a license."

                if user.license:
                    if user.license not in allowed_licenses:
                        report.status = "FAIL"
                        report.status_extended = f"User {user.name} has administrative roles {admin_roles} and an invalid license: {user.license}."
                    else:
                        report.status = "PASS"
                        report.status_extended = f"User {user.name} has administrative roles {admin_roles} and a valid license: {user.license}."

                findings.append(report)

        return findings