SHELL/5.1.3.1.ps1

$CheckId = "5.1.3.1"
$Title = "Ensure a dynamic group for guest users is created"

try {
    $Groups = @(Get-MgGroup -All -Property Id,DisplayName,GroupTypes,MembershipRule,MembershipRuleProcessingState)

    $DynamicGroups = $Groups | Where-Object {
        $_.GroupTypes -and ($_.GroupTypes -contains "DynamicMembership")
    }

    $GuestDynamicGroups = $DynamicGroups | Where-Object {
        $_.MembershipRule -and ($_.MembershipRule -match "(?i)user\.userType\s*-eq\s*['""]Guest['""]")
    }

    $Pass = @($GuestDynamicGroups).Count -gt 0

    [pscustomobject]@{
        CheckId   = $CheckId
        Title     = $Title
        Status    = if ($Pass) { "PASS" } else { "FAIL" }
        Pass      = $Pass
        Evidence  = [pscustomobject]@{
            DynamicGroupCount      = @($DynamicGroups).Count
            GuestDynamicGroupCount = @($GuestDynamicGroups).Count
            GuestDynamicGroups     = @($GuestDynamicGroups | Select-Object Id,DisplayName,MembershipRule,MembershipRuleProcessingState)
            RequiredRuleFragment   = "(user.userType -eq 'Guest')"
        }
        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]@{
            RequiredGraphScope = "Group.Read.All"
            ReviewAction       = "Verify at least one dynamic group includes the rule (user.userType -eq 'Guest')."
        }
        Error     = $Message
        Timestamp = Get-Date
    }
}