tests/Test-Assessment.25375.ps1
|
<#
.SYNOPSIS The tenant holds the licenses required to operate Global Secure Access. .DESCRIPTION This test verifies that the tenant holds the licensing prerequisites for Global Secure Access: - Microsoft Entra ID P1 (foundational requirement) - At least one GSA entitlement with capabilityStatus = "Enabled": * Microsoft Entra Internet Access * Microsoft Entra Private Access * Microsoft Agent 365 Per-user license assignment is intentionally not evaluated. License enforcement for Global Secure Access is applied at the tenant level. .NOTES Test ID: 25375 Category: Global Secure Access Required API: subscribedSkus (beta) GSA Service Plan IDs: - Entra_Premium_Internet_Access: 8d23cb83-ab07-418f-8517-d7aca77307dc - Entra_Premium_Private_Access: f057aab1-b184-49b2-85c0-881b02a405c5 - AGENT_365: d0ce5ebb-9db0-491f-b780-8973a1d815fe #> function Test-Assessment-25375 { [ZtTest( Category = 'Global Secure Access', ImplementationCost = 'Low', Service = ('Graph'), CompatibleLicense = ('AAD_PREMIUM','AAD_PREMIUM_P2'), Pillar = 'Network', RiskLevel = 'High', SfiPillar = 'Protect networks', TenantType = ('Workforce'), TestId = 25375, Title = 'The tenant holds the licenses required to operate Global Secure Access', UserImpact = 'Low' )] [CmdletBinding()] param() #region Data Collection Write-PSFMessage '🟦 Start' -Tag Test -Level VeryVerbose $activity = 'Checking Global Secure Access licensing prerequisites' Write-ZtProgress -Activity $activity -Status 'Querying tenant licenses' # GSA Service Plan IDs $gsaServicePlanIds = @{ InternetAccess = '8d23cb83-ab07-418f-8517-d7aca77307dc' # Entra_Premium_Internet_Access PrivateAccess = 'f057aab1-b184-49b2-85c0-881b02a405c5' # Entra_Premium_Private_Access Agent365 = 'd0ce5ebb-9db0-491f-b780-8973a1d815fe' # AGENT_365 } $errorMsg = $null $subscribedSkus = @() # Q1: Retrieve tenant licenses with GSA service plans try { $subscribedSkus = Invoke-ZtGraphRequest -RelativeUri 'subscribedSkus' -ApiVersion beta -ErrorAction Stop } catch { $errorMsg = $_ Write-PSFMessage "Failed to retrieve subscribed SKUs: $_" -Tag Test -Level Warning } #endregion Data Collection #region Assessment Logic $testResultMarkdown = '' $passed = $false $customStatus = $null # Handle query failure - cannot determine license status if ($errorMsg) { Write-PSFMessage "Unable to retrieve GSA license data due to query failure" -Tag Test -Level Warning $customStatus = 'Investigate' $testResultMarkdown = "⚠️ Unable to determine Global Secure Access licensing prerequisites due to query failure, connection issues, or insufficient permissions.`n`nError: $errorMsg" $params = @{ TestId = '25375' Title = 'The tenant holds the licenses required to operate Global Secure Access' Status = $false Result = $testResultMarkdown CustomStatus = $customStatus } Add-ZtTestResultDetail @params return } # Filter SKUs containing any GSA service plans $gsaSkus = @($subscribedSkus | Where-Object { $_.ServicePlans | Where-Object { $_.ServicePlanId -in $gsaServicePlanIds.Values } }) # Identify which GSA service plans are available with Enabled status $availableServicePlans = @{} foreach ($planKey in $gsaServicePlanIds.Keys) { $planId = $gsaServicePlanIds[$planKey] $availableServicePlans[$planKey] = $false foreach ($sku in $subscribedSkus) { if ($sku.CapabilityStatus -eq 'Enabled') { $matchingPlan = $sku.ServicePlans | Where-Object { $_.ServicePlanId -eq $planId } if ($matchingPlan) { $availableServicePlans[$planKey] = $true break } } } } # Compute licensing signals $hasInternetAccess = $availableServicePlans['InternetAccess'] $hasPrivateAccess = $availableServicePlans['PrivateAccess'] $hasAgent365 = $availableServicePlans['Agent365'] $hasGsaEntitlement = $hasInternetAccess -and $hasPrivateAccess -and $hasAgent365 $hasPartialEntitlement = ($hasInternetAccess -or $hasPrivateAccess -or $hasAgent365) -and (-not $hasGsaEntitlement) # Evaluate results if ($hasGsaEntitlement) { $passed = $true $testResultMarkdown = "✅ The tenant has all active Global Secure Access licensing entitlement.`n`n%TestResult%" } elseif ($hasPartialEntitlement) { $passed = $false $customStatus = 'Investigate' $missingPlans = @() if (-not $hasInternetAccess) { $missingPlans += 'Microsoft Entra Internet Access' } if (-not $hasPrivateAccess) { $missingPlans += 'Microsoft Entra Private Access' } if (-not $hasAgent365) { $missingPlans += 'Microsoft Agent 365' } $missingList = $missingPlans -join ', ' $testResultMarkdown = "⚠️ The tenant is missing some of the Global Secure Access licensing entitlements: $missingList.`n`n%TestResult%" } else { $passed = $false $testResultMarkdown = "❌ The tenant is missing all of the required prerequisites — an active Global Secure Access licensing entitlement for all Microsoft Entra Internet Access, Microsoft Entra Private Access and Microsoft Agent 365.`n`n%TestResult%" } #endregion Assessment Logic #region Report Generation # Always generate report tables for successful queries $reportTitle = 'Licenses' $portalLink = 'https://admin.microsoft.com/Adminportal/Home#/licenses' # Build requirement status table (always shown) $requirementTableRows = '' # Determine source SKUs containing any GSA service plan (regardless of capability status) $gsaSourceSkus = @($gsaSkus | ForEach-Object { Get-SafeMarkdown -Text $_.SkuPartNumber } | Select-Object -Unique) # Single aggregate row per spec $gsaStatus = if ($hasGsaEntitlement) { '✅ Enabled' } else { '❌ Missing' } $gsaSkuList = if ($gsaSourceSkus.Count -gt 0) { $gsaSourceSkus -join ', ' } else { '—' } $requirementTableRows += "| Global Secure Access licensing entitlement | $gsaStatus | $gsaSkuList |`n" # Build SKU details table $skuDetailRows = '' $countHeader = '' if ($gsaSkus.Count -gt 0) { $maxDisplay = 10 $totalSkus = $gsaSkus.Count $displaySkus = if ($totalSkus -gt $maxDisplay) { $gsaSkus | Select-Object -First $maxDisplay } else { $gsaSkus } # Add count header if truncation occurs if ($totalSkus -gt $maxDisplay) { $countHeader = "Showing $maxDisplay of $totalSkus SKUs.`n`n" } foreach ($sku in $displaySkus) { $skuName = Get-SafeMarkdown -Text $sku.SkuPartNumber $capabilityStatus = $sku.CapabilityStatus # List tracked service plans in this SKU $trackedPlans = @($sku.ServicePlans | Where-Object { $_.ServicePlanId -in $gsaServicePlanIds.Values } | ForEach-Object { Get-SafeMarkdown -Text $_.ServicePlanName }) $planList = if ($trackedPlans.Count -gt 0) { $trackedPlans -join ', ' } else { '—' } $available = $sku.PrepaidUnits.Enabled $assigned = $sku.ConsumedUnits $skuDetailRows += "| $skuName | $capabilityStatus | $planList | $available | $assigned |`n" } if ($totalSkus -gt $maxDisplay) { $remaining = $totalSkus - $maxDisplay $skuDetailRows += "| ... ($remaining more) | | | | |`n" } } else { # No SKUs with tracked service plans found $skuDetailRows = "| No SKUs containing tracked Global Secure Access service plans found | | | | |`n" } # Build complete table with header row $tableWithHeader = "| SKU Name | Capability Status | Tracked Service Plans Included | Available | Assigned |`n" $tableWithHeader += "| :------- | :---------------- | :----------------------------- | --------: | -------: |`n" $tableWithHeader += $skuDetailRows $formatTemplate = @' ## [{0}]({1}) **Tenant Licensing Summary:** | Requirement | Status | Source SKU(s) | | :---------- | :----- | :------------ | {2} **SKUs Containing Tracked Service Plans:** {4}{3} '@ $mdInfo = $formatTemplate -f $reportTitle, $portalLink, $requirementTableRows, $tableWithHeader, $countHeader $testResultMarkdown = $testResultMarkdown -replace '%TestResult%', $mdInfo #endregion Report Generation $params = @{ TestId = '25375' Title = 'The tenant holds the licenses required to operate Global Secure Access' Status = $passed Result = $testResultMarkdown } if ($customStatus) { $params.CustomStatus = $customStatus } Add-ZtTestResultDetail @params } |