Src/Private/Get-AbrIntuneSecurityBaselines.ps1
|
function Get-AbrIntuneSecurityBaselines { <# .SYNOPSIS Documents Intune Security Baselines and Endpoint Security policies. .DESCRIPTION Collects and reports on: - Security Baseline profiles (MDM Security Baseline, Defender for Endpoint, etc.) - Per-profile assignment and compliance state .NOTES Version: 0.1.0 Author: Pai Wei Sing #> [CmdletBinding()] param ( [Parameter(Position = 0, Mandatory)] [string]$TenantId ) begin { Write-PScriboMessage -Message "Collecting Intune Security Baselines for $TenantId." Show-AbrDebugExecutionTime -Start -TitleMessage 'Security Baselines' } process { Section -Style Heading2 'Security Baselines' { Paragraph "The following section documents Security Baseline profiles configured in tenant $TenantId." BlankLine try { Write-Host " - Retrieving security baseline templates..." # /beta required -- deviceManagement/intents is beta-only $BaselineIntentsResp = Invoke-MgGraphRequest -Method GET ` -Uri "$($script:GraphEndpoint)/beta/deviceManagement/intents?`$expand=assignments" ` -ErrorAction SilentlyContinue $BaselineIntents = $BaselineIntentsResp.value if ($BaselineIntents -and @($BaselineIntents).Count -gt 0) { $BaselineObj = [System.Collections.ArrayList]::new() foreach ($Intent in ($BaselineIntents | Sort-Object displayName)) { $assignResolved = Resolve-IntuneAssignments -Assignments $Intent.assignments -CheckMemberCount:$script:CheckEmptyGroups $AssignedTo = $assignResolved.AssignmentSummary $scopeTagStr = if ($script:ResolveScopeTagNames -and $Intent.roleScopeTagIds) { Get-IntuneScopeTagNames -ScopeTagIds $Intent.roleScopeTagIds } else { 'Default' } $baselineInObj = [ordered] @{ 'Baseline Name' = $Intent.displayName 'Template ID' = if ($Intent.templateId) { $Intent.templateId } else { '--' } 'Is Assigned' = ($Intent.isAssigned -eq $true) 'Included Groups' = $assignResolved.IncludedGroups 'Excluded Groups' = if ($script:ShowExcludedGroups) { $assignResolved.ExcludedGroups } else { $null } 'Scope Tags' = $scopeTagStr 'Last Modified' = if ($Intent.lastModifiedDateTime) { ([datetime]$Intent.lastModifiedDateTime).ToString('yyyy-MM-dd') } else { '--' } } $BaselineObj.Add([pscustomobject](ConvertTo-HashToYN $baselineInObj)) | Out-Null } $null = (& { if ($HealthCheck.Intune.SecurityBaselines) { $null = ($BaselineObj | Where-Object { $_.'Included Groups' -eq '--' } | Set-Style -Style Warning | Out-Null) } }) $BaselineTableParams = @{ Name = "Security Baseline Profiles - $TenantId"; ColumnWidths = 24, 18, 9, 22, 12, 8, 7 } if ($Report.ShowTableCaptions) { $BaselineTableParams['Caption'] = "- $($BaselineTableParams.Name)" } $BaselineObj | Table @BaselineTableParams if (Get-IntuneBackupSectionEnabled -SectionKey 'SecurityBaselines') { $script:BackupData['SecurityBaselines'] = $BaselineIntents } if (Get-IntuneExcelSheetEnabled -SheetKey 'SecurityBaselines') { $script:ExcelSheets['Security Baselines'] = $BaselineObj } $null = ($script:TotalSecurityBaselines = @($BaselineIntents).Count) #region InfoLevel 2 -- per-baseline detail + settings if ($InfoLevel.SecurityBaselines -ge 2) { foreach ($Intent in ($BaselineIntents | Sort-Object displayName)) { $assignResolved = Resolve-IntuneAssignments -Assignments $Intent.assignments Section -Style Heading3 $Intent.displayName { BlankLine # Overview $ovObj = [System.Collections.ArrayList]::new() $ovObj.Add([pscustomobject]@{ Setting = 'Baseline Name'; Value = $Intent.displayName }) | Out-Null $ovObj.Add([pscustomobject]@{ Setting = 'Template ID'; Value = if ($Intent.templateId) { $Intent.templateId } else { '--' } }) | Out-Null $ovObj.Add([pscustomobject]@{ Setting = 'Is Assigned'; Value = if ($Intent.isAssigned) { 'Yes' } else { 'No' } }) | Out-Null $ovObj.Add([pscustomobject]@{ Setting = 'Included Groups'; Value = $assignResolved.IncludedGroups }) | Out-Null $ovObj.Add([pscustomobject]@{ Setting = 'Excluded Groups'; Value = $assignResolved.ExcludedGroups }) | Out-Null $ovObj.Add([pscustomobject]@{ Setting = 'Last Modified'; Value = if ($Intent.lastModifiedDateTime) { ([datetime]$Intent.lastModifiedDateTime).ToString('yyyy-MM-dd') } else { '--' } }) | Out-Null $OvParams = @{ Name = "Baseline Overview - $($Intent.displayName)"; ColumnWidths = 30, 70 } if ($Report.ShowTableCaptions) { $OvParams['Caption'] = "- $($OvParams.Name)" } $ovObj | Table @OvParams # Fetch categories and settings for this baseline try { $CatResp = Invoke-MgGraphRequest -Method GET ` -Uri "$($script:GraphEndpoint)/beta/deviceManagement/intents/$($Intent.id)/categories" ` -ErrorAction SilentlyContinue $Categories = $CatResp.value if ($Categories -and @($Categories).Count -gt 0) { $settingsRows = [System.Collections.ArrayList]::new() foreach ($Cat in $Categories) { try { $SetResp = Invoke-MgGraphRequest -Method GET ` -Uri "$($script:GraphEndpoint)/beta/deviceManagement/intents/$($Intent.id)/categories/$($Cat.id)/settings" ` -ErrorAction SilentlyContinue foreach ($setting in $SetResp.value) { $val = if ($null -ne $setting.value) { "$($setting.value)" } else { 'Not configured' } if ($val -in @('notConfigured','notSet','','null')) { continue } $settingsRows.Add([pscustomobject]([ordered]@{ 'Category' = $Cat.displayName 'Setting' = if ($setting.definitionId) { ($setting.definitionId -split '_' | Select-Object -Last 1) -creplace '([A-Z])', ' $1' -replace '^\s+','' } else { $setting.id } 'Value' = if ($val.Length -gt 80) { "$($val.Substring(0,80))..." } else { $val } })) | Out-Null } } catch { } } if ($settingsRows.Count -gt 0) { BlankLine Paragraph "Configured Settings ($($settingsRows.Count) setting(s)):" BlankLine $SetParams = @{ Name = "Settings - $($Intent.displayName)"; ColumnWidths = 25, 40, 35 } if ($Report.ShowTableCaptions) { $SetParams['Caption'] = "- $($SetParams.Name)" } $settingsRows | Table @SetParams } } } catch { Paragraph "Could not retrieve settings: $($_.Exception.Message)" } } } } #endregion } else { Paragraph "No Security Baseline profiles found in tenant $TenantId." } } catch { if (Test-AbrGraphForbidden -ErrorRecord $_) { Write-AbrPermissionError -Section 'Security Baselines' -RequiredRole 'Intune Service Administrator or Global Administrator' } else { Write-AbrSectionError -Section 'Security Baselines' -Message "$($_.Exception.Message)" } } } } end { Show-AbrDebugExecutionTime -End -TitleMessage 'Security Baselines' } } |