SHELL/5.2.2.11.ps1

$CheckId = "5.2.2.11"
$Title = "Ensure sign-in frequency for Intune Enrollment is set to 'Every time'"
$Level = "L1"
$BenchmarkType = "Automated"
$HelperPath = Join-Path $PSScriptRoot "helpers\ca_policy_helpers.ps1"

function Get-IntuneEnrollmentTargetIds {
    $Ids = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase)

    foreach ($KnownId in @(
            "d4ebce55-015a-49b5-a083-c84d1797ae8c"  # Microsoft Intune
        )) {
        [void]$Ids.Add($KnownId)
    }

    $EnvIds = @([string]$env:ROOT365_INTUNE_ENROLLMENT_APP_IDS -split '[,; ]+' | ForEach-Object { $_.Trim() } | Where-Object { $_ })
    foreach ($EnvId in $EnvIds) {
        [void]$Ids.Add($EnvId)
    }

    try {
        $Uri = "https://graph.microsoft.com/beta/servicePrincipals?`$filter=displayName eq 'Microsoft Intune Enrollment'&`$select=id,appId,displayName"
        $Response = Invoke-MgGraphRequest -Uri $Uri -Method GET -ErrorAction Stop
        foreach ($Sp in @($Response.value)) {
            if ($Sp.id) { [void]$Ids.Add([string]$Sp.id) }
            if ($Sp.appId) { [void]$Ids.Add([string]$Sp.appId) }
        }
    }
    catch {
        # Keep deterministic behavior with known IDs if service principal lookup is unavailable.
    }

    return @($Ids)
}

try {
    if (-not (Test-Path $HelperPath)) {
        throw "Required helper file not found: $HelperPath"
    }

    . $HelperPath

    $IntuneTargetIds = @(Get-IntuneEnrollmentTargetIds)
    $Policies = @(Get-Root365CaPoliciesNormalized)
    if ($Policies.Count -eq 0) {
        [pscustomobject]@{
            CheckId = $CheckId
            Title = $Title
            Level = $Level
            BenchmarkType = $BenchmarkType
            Status = "FAIL"
            Pass = $false
            Evidence = [pscustomobject]@{
                HelperPath = $HelperPath
                ConditionalAccessPolicyCount = 0
                SourceDocument = "CIS_Microsoft_365_Foundations_Benchmark_v6.0.1"
            }
            Error = "No Conditional Access policies were returned."
            Timestamp = Get-Date
        }
        return
    }

    $EnabledPolicies = @($Policies | Where-Object { $_.IsEnabled })
    $MatchedPolicies = @(
        $EnabledPolicies | Where-Object {
            $TargetsIntuneEnrollment = @($_.IncludeApplications | Where-Object { $_ -in $IntuneTargetIds })
            $GrantHasMfaOrStrength =
                (Test-Root365ContainsValue -Collection $_.GrantBuiltInControls -Expected "mfa") -or
                -not [string]::IsNullOrWhiteSpace([string]$_.AuthenticationStrengthId) -or
                -not [string]::IsNullOrWhiteSpace([string]$_.AuthenticationStrengthDisplayName)

            (Test-Root365ContainsValue -Collection $_.IncludeUsers -Expected "All") -and
            ($TargetsIntuneEnrollment.Count -gt 0) -and
            $GrantHasMfaOrStrength -and
            (Test-Root365SignInFrequencyEveryTime -Policy $_)
        }
    )

    $Pass = $MatchedPolicies.Count -gt 0
    $Status = if ($Pass) { "PASS" } else { "FAIL" }

    [pscustomobject]@{
        CheckId = $CheckId
        Title = $Title
        Level = $Level
        BenchmarkType = $BenchmarkType
        Status = $Status
        Pass = $Pass
        Evidence = [pscustomobject]@{
            ConditionalAccessPolicyCount = $Policies.Count
            EnabledPolicyCount = $EnabledPolicies.Count
            IntuneEnrollmentTargetIds = $IntuneTargetIds
            IntuneEnrollmentIdsSource = "Known ID + service principal lookup + ROOT365_INTUNE_ENROLLMENT_APP_IDS"
            MatchedPolicyCount = $MatchedPolicies.Count
            MatchedPolicies = @(Get-Root365CaPolicyEvidenceSummary -Policies $MatchedPolicies)
            ComplianceCriteria = "Enabled CA policy targets Intune Enrollment and enforces MFA/authentication strength with sign-in frequency Every time."
            SourceDocument = "CIS_Microsoft_365_Foundations_Benchmark_v6.0.1"
        }
        Error = if ($Pass) { $null } else { "No enabled Conditional Access policy was found that targets Microsoft Intune Enrollment and enforces every-time sign-in frequency with MFA/auth strength." }
        Timestamp = Get-Date
    }
}
catch {
    [pscustomobject]@{
        CheckId = $CheckId
        Title = $Title
        Level = $Level
        BenchmarkType = $BenchmarkType
        Status = "ERROR"
        Pass = $null
        Evidence = [pscustomobject]@{
            HelperPath = $HelperPath
            SourceDocument = "CIS_Microsoft_365_Foundations_Benchmark_v6.0.1"
        }
        Error = $_.Exception.Message
        Timestamp = Get-Date
    }
}