SHELL/1.1.4.ps1

$CheckId = "1.1.4"
$Title = "Ensure administrative accounts use licenses with a reduced application footprint"
$Level = "L1"
$BenchmarkType = "Automated"

try {
    $RunStamp = Get-Date -Format "yyyyMMdd_HHmmss"
    $ProjectRoot = Split-Path -Path $PSScriptRoot -Parent
    $ManualReviewDir = Join-Path $ProjectRoot "manual_review"
    if (-not (Test-Path $ManualReviewDir)) {
        New-Item -Path $ManualReviewDir -ItemType Directory -Force | Out-Null
    }
    $CsvExportPath = Join-Path $ManualReviewDir "1.1.4_admin_accounts_$RunStamp.csv"

    $AllowedSkus = @(
        "AAD_PREMIUM",
        "AAD_PREMIUM_P2",
        "INTUNE_A",
        "INTUNE_EDU",
        "EMSPREMIUM",
        "EMS",
        "RIGHTSMANAGEMENT",
        "THREAT_INTELLIGENCE",
        "ATP_ENTERPRISE",
        "ATA",
        "ADALLOM_STANDALONE",
        "IDENTITY_THREAT_PROTECTION"
    )

    $AllRoles = @(Get-MgDirectoryRole -All -ErrorAction Stop)
    $AdminRoles = @($AllRoles | Where-Object { [string]$_.DisplayName -match "(?i)administrator" })

    $AdminUserIds = @()
    foreach ($Role in $AdminRoles) {
        $Members = @(Get-MgDirectoryRoleMember -DirectoryRoleId $Role.Id -All -ErrorAction Stop)
        foreach ($Member in $Members) {
            if ([string]$Member.AdditionalProperties.'@odata.type' -eq "#microsoft.graph.user") {
                $AdminUserIds += [string]$Member.Id
            }
        }
    }
    $AdminUserIds = @($AdminUserIds | Select-Object -Unique)

    $AdminReport = @()
    $AdminsWithHeavyLicenses = @()
    foreach ($UserId in $AdminUserIds) {
        $User = Get-MgUser -UserId $UserId -Property UserPrincipalName,DisplayName -ErrorAction SilentlyContinue
        $Licenses = @(Get-MgUserLicenseDetail -UserId $UserId -ErrorAction SilentlyContinue)
        $SkuParts = @($Licenses | ForEach-Object { [string]$_.SkuPartNumber } | Where-Object { $_ } | Select-Object -Unique)
        $DisallowedSkus = @($SkuParts | Where-Object { $_ -notin $AllowedSkus })

        $Row = [pscustomobject]@{
            UserId = $UserId
            UserPrincipalName = [string]$User.UserPrincipalName
            DisplayName = [string]$User.DisplayName
            LicenseSkus = @($SkuParts) -join "; "
            DisallowedSkus = @($DisallowedSkus) -join "; "
            IsReducedFootprint = (@($DisallowedSkus).Count -eq 0)
        }
        $AdminReport += $Row

        if (@($DisallowedSkus).Count -gt 0) {
            $AdminsWithHeavyLicenses += $Row
        }
    }

    $AdminReport | Sort-Object UserPrincipalName | Export-Csv -Path $CsvExportPath -NoTypeInformation -Encoding UTF8

    $Pass = (@($AdminsWithHeavyLicenses).Count -eq 0)
    $Status = if ($Pass) { "PASS" } else { "FAIL" }

    [pscustomobject]@{
        CheckId = $CheckId
        Title = $Title
        Level = $Level
        BenchmarkType = $BenchmarkType
        Status = $Status
        Pass = $Pass
        Evidence = [pscustomobject]@{
            AdminRoleCount = @($AdminRoles).Count
            AdminUserCount = @($AdminUserIds).Count
            AllowedSkus = @($AllowedSkus)
            AdminsWithHeavyLicensesCount = @($AdminsWithHeavyLicenses).Count
            AdminsWithHeavyLicensesPreview = @($AdminsWithHeavyLicenses | Select-Object -First 50)
            CsvExportPath = $CsvExportPath
            CsvRowCount = @($AdminReport).Count
            SourceDocument = "CIS_Microsoft_365_Foundations_Benchmark_v6.0.1"
        }
        Error = if ($Pass) { $null } else { "One or more administrative accounts have application-bearing licenses outside the allowed reduced-footprint SKU list." }
        Timestamp = Get-Date
    }
}
catch {
    [pscustomobject]@{
        CheckId = $CheckId
        Title = $Title
        Level = $Level
        BenchmarkType = $BenchmarkType
        Status = "ERROR"
        Pass = $null
        Evidence = [pscustomobject]@{
            SourceDocument = "CIS_Microsoft_365_Foundations_Benchmark_v6.0.1"
        }
        Error = $_.Exception.Message
        Timestamp = Get-Date
    }
}