Private/Baseline/Import-McsbBaseline.ps1
|
function Import-McsbBaseline { <# .SYNOPSIS Import Microsoft Cloud Security Benchmark baseline from Azure. .DESCRIPTION Retrieves the MCSB initiative from Azure and expands all member policies. Resolves policy definitions and effects for each policy in the initiative. .PARAMETER InitiativeDisplayName Display name of the MCSB initiative. Default: "Microsoft cloud security benchmark" .PARAMETER ManagementGroupId Management Group scope for querying the initiative. .PARAMETER PolicyDefinitionCache Hashtable cache for policy definitions (improves performance). .PARAMETER PolicySetDefinitionCache Hashtable cache for policy set definitions. .EXAMPLE $mcsbBaseline = Import-McsbBaseline -PolicyDefinitionCache $cache .OUTPUTS Array of MCSB policy baseline objects #> [CmdletBinding()] param( [string]$InitiativeDisplayName = "Microsoft cloud security benchmark", [string]$ManagementGroupId, [hashtable]$PolicyDefinitionCache = @{}, [hashtable]$PolicySetDefinitionCache = @{} ) $baselineCombined = @() try { Write-Host "" Write-Host "🔍 Loading MCSB Baseline..." -ForegroundColor Cyan Write-Host (" ├─ Searching for: '{0}'" -f $InitiativeDisplayName) -ForegroundColor DarkCyan # Find MCSB initiative $mcsbSet = Get-PolicySetDefinitionCached ` -ManagementGroupId $ManagementGroupId ` -Cache $PolicySetDefinitionCache | Where-Object { $_.DisplayName -eq $InitiativeDisplayName } | Select-Object -First 1 if (-not $mcsbSet) { Write-Warning ("⚠️ MCSB initiative not found with DisplayName: '{0}'" -f $InitiativeDisplayName) Write-Warning " Available built-in security initiatives:" Get-PolicySetDefinitionCached ` -ManagementGroupId $ManagementGroupId ` -Cache $PolicySetDefinitionCache | Where-Object { $_.PolicyType -eq 'BuiltIn' -and $_.DisplayName -like "*security*" } | Select-Object -First 5 -Property DisplayName | ForEach-Object { Write-Host (" • {0}" -f $_.DisplayName) -ForegroundColor DarkYellow } return $baselineCombined } $mcsbTotal = $mcsbSet.PolicyDefinition.Count $mcsbIndex = 0 Write-Host (" ├─ Found MCSB initiative: {0}" -f $mcsbSet.DisplayName) -ForegroundColor Green Write-Host (" ├─ Initiative ID: {0}" -f $mcsbSet.Id) -ForegroundColor DarkGray Write-Host (" └─ Loading {0} policies..." -f $mcsbTotal) -ForegroundColor DarkCyan Write-Host "" # Expand each policy in the initiative foreach ($ref in $mcsbSet.PolicyDefinition) { $mcsbIndex++ # Progress bar every 20 policies if ($mcsbIndex % 20 -eq 0 -or $mcsbIndex -eq $mcsbTotal) { $percent = [math]::Round(($mcsbIndex / $mcsbTotal) * 100, 1) $barLength = 50 $filled = [math]::Round($percent / 2) $bar = ('█' * $filled) + ('░' * ($barLength - $filled)) Write-Host ("[{0}] {1}% | {2}/{3} MCSB policies" -f $bar, $percent, $mcsbIndex, $mcsbTotal) -ForegroundColor Cyan } try { $pol = Get-PolicyDefinitionCached ` -PolicyDefinitionId $ref.PolicyDefinitionId ` -Cache $PolicyDefinitionCache # Resolve effect $effectValue = Resolve-PolicyEffect ` -Ref $ref ` -PolicyDefinition $pol ` -PolicyDisplayName $pol.DisplayName ` -PolicyDefinitionId $pol.Id $baselineCombined += [pscustomobject]@{ PolicyDefinitionId = $pol.Id PolicyDisplayName = $pol.DisplayName PolicyType = $pol.PolicyType Version = $pol.Metadata.version BaselineSources = "MCSB" Effect = $effectValue } } catch { Write-Debug "Failed to resolve policy: $($ref.PolicyDefinitionId) - $($_.Exception.Message)" $baselineCombined += [pscustomobject]@{ PolicyDefinitionId = $ref.PolicyDefinitionId PolicyDisplayName = "[Unresolved] $($ref.PolicyDefinitionId)" PolicyType = $null Version = $null BaselineSources = "MCSB" Effect = "N/A" } } } Write-Host "" Write-Host ("✅ MCSB Baseline loaded: {0} policies" -f $mcsbIndex) -ForegroundColor Green } catch { Write-Warning "Error loading MCSB: $($_.Exception.Message)" } return $baselineCombined } |