|
| 1 | +<# |
| 2 | +.SYNOPSIS |
| 3 | + Checks whether Microsoft Sentinel is onboarded on at least one Log Analytics workspace. |
| 4 | +
|
| 5 | +.DESCRIPTION |
| 6 | + This test enumerates all Log Analytics workspaces across in-scope Azure subscriptions and |
| 7 | + verifies that at least one has Microsoft Sentinel onboarded. Sentinel is required as a central |
| 8 | + SIEM before any other AI threat detection control in this pillar can correlate signals across |
| 9 | + the environment. |
| 10 | +
|
| 11 | + Evaluation steps: |
| 12 | + 1. Use Azure Resource Graph to enumerate all Log Analytics workspaces (combining subscription |
| 13 | + listing and workspace listing in one query). |
| 14 | + 2. For each workspace, query the Sentinel onboarding state resource via the |
| 15 | + Microsoft.SecurityInsights/onboardingStates/default ARM endpoint. |
| 16 | + 3. Pass if at least one workspace returns HTTP 200 (Sentinel is onboarded). |
| 17 | + 4. Fail if workspaces exist but every one returns HTTP 404 (Sentinel not onboarded). |
| 18 | + 5. Skip if no Log Analytics workspaces are found across accessible subscriptions. |
| 19 | +
|
| 20 | +.NOTES |
| 21 | + Test ID: 61002 |
| 22 | + Workshop Task: AI_089 |
| 23 | + Pillar: AI |
| 24 | + Category: AI Threat Detection |
| 25 | + Required permissions: |
| 26 | + - Reader on each subscription (for Log Analytics workspace enumeration) |
| 27 | + - Microsoft Sentinel Reader on each workspace (for onboarding state query) |
| 28 | +#> |
| 29 | + |
| 30 | +function Test-Assessment-61002 { |
| 31 | + |
| 32 | + [ZtTest( |
| 33 | + Category = 'AI Threat Detection', |
| 34 | + ImplementationCost = 'Medium', |
| 35 | + Service = ('Azure'), |
| 36 | + MinimumLicense = ('Microsoft_Sentinel'), |
| 37 | + Pillar = 'AI', |
| 38 | + RiskLevel = 'High', |
| 39 | + SfiPillar = 'Monitor and detect cyberthreats', |
| 40 | + TenantType = ('Workforce'), |
| 41 | + TestId = 61002, |
| 42 | + Title = 'Microsoft Sentinel is onboarded on at least one Log Analytics workspace', |
| 43 | + UserImpact = 'Low' |
| 44 | + )] |
| 45 | + [CmdletBinding()] |
| 46 | + param() |
| 47 | + |
| 48 | + #region Data Collection |
| 49 | + Write-PSFMessage '🟦 Start' -Tag Test -Level VeryVerbose |
| 50 | + $activity = 'Evaluating Microsoft Sentinel onboarding state across Log Analytics workspaces' |
| 51 | + |
| 52 | + # Delegate all data fetching (Q1+Q2+Q3) to the private helper. |
| 53 | + # 'Forbidden' signals a 403 on the ARG workspace query (spec: Investigate). |
| 54 | + # $null signals any other ARG failure. |
| 55 | + # An empty array signals no workspaces found (spec: Skip). |
| 56 | + $workspaceResults = Get-SentinelWorkspaceData -Activity $activity |
| 57 | + |
| 58 | + # Per spec: Q2 returns 403 → Investigate. |
| 59 | + if ($workspaceResults -eq 'Forbidden') { |
| 60 | + $params = @{ |
| 61 | + TestId = '61002' |
| 62 | + Title = 'Microsoft Sentinel is onboarded on at least one Log Analytics workspace' |
| 63 | + Status = $false |
| 64 | + Result = '⚠️ Some of the queried resources returned status indicating insufficient permissions. Please make sure you have at least reader access to the Azure subscriptions being tested.' |
| 65 | + CustomStatus = 'Investigate' |
| 66 | + } |
| 67 | + Add-ZtTestResultDetail @params |
| 68 | + return |
| 69 | + } |
| 70 | + |
| 71 | + # $null signals a non-403 ARG failure. |
| 72 | + if ($null -eq $workspaceResults) { |
| 73 | + Add-ZtTestResultDetail -SkippedBecause NotSupported |
| 74 | + return |
| 75 | + } |
| 76 | + |
| 77 | + # Per spec: zero workspaces → Skipped, not Failed. |
| 78 | + if ($workspaceResults.Count -eq 0) { |
| 79 | + Write-PSFMessage 'No Log Analytics workspaces found across accessible subscriptions.' -Tag Test -Level VeryVerbose |
| 80 | + Add-ZtTestResultDetail -SkippedBecause NotApplicable |
| 81 | + return |
| 82 | + } |
| 83 | + #endregion Data Collection |
| 84 | + |
| 85 | + #region Assessment Logic |
| 86 | + $onboardedWorkspaces = @($workspaceResults | Where-Object { $_.SentinelOnboarded }) |
| 87 | + $passed = $onboardedWorkspaces.Count -ge 1 |
| 88 | + |
| 89 | + if ($passed) { |
| 90 | + $testResultMarkdown = "✅ Microsoft Sentinel is onboarded on at least one Log Analytics workspace.`n`n%TestResult%" |
| 91 | + } |
| 92 | + else { |
| 93 | + $testResultMarkdown = "❌ No Log Analytics workspace in scope has Microsoft Sentinel onboarded.`n`n%TestResult%" |
| 94 | + } |
| 95 | + #endregion Assessment Logic |
| 96 | + |
| 97 | + #region Report Generation |
| 98 | + $workspacesPortalUrl = 'https://portal.azure.com/#view/HubsExtension/BrowseResource/resourceType/Microsoft.OperationalInsights%2Fworkspaces' |
| 99 | + $workspacePortalTemplate = 'https://portal.azure.com/#resource{0}/overview' |
| 100 | + |
| 101 | + $formatTemplate = @' |
| 102 | +
|
| 103 | +
|
| 104 | +### [{0}]({1}) |
| 105 | +
|
| 106 | +| Subscription | Workspace | Resource group | Sentinel onboarded | |
| 107 | +| :----------- | :-------- | :------------- | :----------------- | |
| 108 | +{2} |
| 109 | +
|
| 110 | +**Summary:** |
| 111 | +
|
| 112 | +- Total workspaces: {3} |
| 113 | +- Workspaces with Sentinel onboarded: {4} |
| 114 | +'@ |
| 115 | + |
| 116 | + $onboardedCount = $onboardedWorkspaces.Count |
| 117 | + |
| 118 | + $tableRows = '' |
| 119 | + foreach ($result in $workspaceResults) { |
| 120 | + $subscriptionName = Get-SafeMarkdown -Text $result.SubscriptionName |
| 121 | + $workspaceName = Get-SafeMarkdown -Text $result.WorkspaceName |
| 122 | + $resourceGroup = Get-SafeMarkdown -Text $result.ResourceGroup |
| 123 | + $workspaceLink = "[$workspaceName]($($workspacePortalTemplate -f $result.WorkspaceId))" |
| 124 | + $onboardedLabel = if ($result.SentinelOnboarded) { '✅ Yes' } else { '❌ No' } |
| 125 | + $tableRows += "| $subscriptionName | $workspaceLink | $resourceGroup | $onboardedLabel |`n" |
| 126 | + } |
| 127 | + |
| 128 | + $mdInfo = $formatTemplate -f 'Workspaces and their Sentinel onboarding state', $workspacesPortalUrl, $tableRows, $workspaceResults.Count, $onboardedCount |
| 129 | + |
| 130 | + $testResultMarkdown = $testResultMarkdown -replace '%TestResult%', $mdInfo |
| 131 | + #endregion Report Generation |
| 132 | + |
| 133 | + $params = @{ |
| 134 | + TestId = '61002' |
| 135 | + Title = 'Microsoft Sentinel is onboarded on at least one Log Analytics workspace' |
| 136 | + Status = $passed |
| 137 | + Result = $testResultMarkdown |
| 138 | + } |
| 139 | + |
| 140 | + Add-ZtTestResultDetail @params |
| 141 | +} |
0 commit comments