SHELL/5.1.4.4.ps1

$CheckId = "5.1.4.4"
$Title = "Ensure local administrator assignment is limited during Entra join"

function Get-NestedValue {
    param(
        [Parameter(Mandatory = $true)][object]$InputObject,
        [Parameter(Mandatory = $true)][string[]]$Path
    )

    $Current = $InputObject
    foreach ($Segment in $Path) {
        if ($null -eq $Current) {
            return $null
        }

        if ($Current -is [System.Collections.IDictionary]) {
            if ($Current.Contains($Segment)) {
                $Current = $Current[$Segment]
            }
            else {
                return $null
            }
        }
        else {
            $Prop = $Current.PSObject.Properties[$Segment]
            if ($null -eq $Prop) {
                return $null
            }
            $Current = $Prop.Value
        }
    }
    return $Current
}

$Uri = "https://graph.microsoft.com/beta/policies/deviceRegistrationPolicy"

try {
    $Policy = Invoke-MgGraphRequest -Method GET -Uri $Uri
    $RegisteringUsers = Get-NestedValue -InputObject $Policy -Path @("azureADJoin", "localAdmins", "registeringUsers")
    $RegisteringUsersType = Get-NestedValue -InputObject $Policy -Path @("azureADJoin", "localAdmins", "registeringUsers", "@odata.type")

    if ([string]::IsNullOrWhiteSpace([string]$RegisteringUsersType)) {
        [pscustomobject]@{
            CheckId   = $CheckId
            Title     = $Title
            Status    = "MANUAL_REVIEW"
            Pass      = $null
            Evidence  = [pscustomobject]@{
                Uri                  = $Uri
                registeringUsers     = $RegisteringUsers
                ReviewAction         = "Verify registeringUsers is Selected or None."
            }
            Error     = "Could not determine registeringUsers @odata.type."
            Timestamp = Get-Date
        }
    }
    else {
        $CompliantTypes = @(
            "#microsoft.graph.enumeratedDeviceRegistrationMembership",
            "#microsoft.graph.noDeviceRegistrationMembership"
        )
        $Pass = $RegisteringUsersType -in $CompliantTypes

        [pscustomobject]@{
            CheckId   = $CheckId
            Title     = $Title
            Status    = if ($Pass) { "PASS" } else { "FAIL" }
            Pass      = $Pass
            Evidence  = [pscustomobject]@{
                Uri                   = $Uri
                RegisteringUsersType  = $RegisteringUsersType
                RegisteringUsers      = $RegisteringUsers
                CompliantTypes        = $CompliantTypes
            }
            Error     = $null
            Timestamp = Get-Date
        }
    }
}
catch {
    $Message = $_.Exception.Message
    $IsPermissionIssue = $Message -match "(?i)forbidden|insufficient|authorization|access denied"

    [pscustomobject]@{
        CheckId   = $CheckId
        Title     = $Title
        Status    = if ($IsPermissionIssue) { "MANUAL_REVIEW" } else { "ERROR" }
        Pass      = $null
        Evidence  = [pscustomobject]@{
            Uri                   = $Uri
            RequiredGraphScope    = "Policy.Read.DeviceConfiguration"
            ReviewAction          = "Verify registeringUsers type is enumeratedDeviceRegistrationMembership (Selected) or noDeviceRegistrationMembership (None)."
        }
        Error     = $Message
        Timestamp = Get-Date
    }
}