Public/Get-NLBaselineCASecurityAdvisory.ps1
|
function Get-NLBaselineCASecurityAdvisory { <# .SYNOPSIS Generate Security Advisory with AI support .DESCRIPTION Analyzes Conditional Access policies with AI and provides advice, gaps, and recommendations .EXAMPLE Get-NLBaselineCASecurityAdvisory #> [CmdletBinding()] param() try { # Get module configuration $moduleConfigPath = Get-ConfigPath if (-not (Test-Path $moduleConfigPath)) { Write-Error "Module configuration not found. Run Quick Start first." return } $moduleConfig = Get-Content $moduleConfigPath | ConvertFrom-Json $storagePath = $moduleConfig.StoragePath if (-not (Test-Path $storagePath)) { Write-Error "Storage path not found: $storagePath. Run Quick Start to configure." return } # Get config.json from storage path $configPath = Join-Path $storagePath "config.json" if (-not (Test-Path $configPath)) { Write-Error "Configuration file not found: $configPath. Run Quick Start to configure." return } $config = Get-Content $configPath | ConvertFrom-Json # Check AI configuration if ([string]::IsNullOrWhiteSpace($config.OpenAIEndpoint) -or [string]::IsNullOrWhiteSpace($config.OpenAIApiKey)) { Write-Error "AI configuration is incomplete. Check: $configPath" Write-Host "Run Quick Start to configure AI settings." -ForegroundColor Yellow return } # Create AI config object for compatibility # Default to gpt-4o for better quality and higher rate limits $aiConfig = @{ endpoint = $config.OpenAIEndpoint apiKey = $config.OpenAIApiKey model = if ($config.OpenAIModel) { $config.OpenAIModel } else { "gpt-4o" } } Write-Host "Using AI model: $($aiConfig.model)" -ForegroundColor Gray Write-Host "Generating Security Advisory with AI..." -ForegroundColor Yellow Write-Host "" # Create/clean AI folder for fresh export $aiPoliciesPath = Join-Path $storagePath "AI" if (Test-Path $aiPoliciesPath) { Write-Host "Cleaning AI folder for fresh export..." -ForegroundColor Yellow Remove-Item -Path $aiPoliciesPath -Recurse -Force -ErrorAction SilentlyContinue } New-Item -Path $aiPoliciesPath -ItemType Directory -Force | Out-Null Write-Host "AI folder created: $aiPoliciesPath" -ForegroundColor Gray Write-Host "" # Check connection before exporting $context = Get-MgContext -ErrorAction SilentlyContinue if (-not $context -or -not $context.TenantId) { Write-Host "Not connected to Microsoft 365. Connecting..." -ForegroundColor Yellow Write-Host "" $connection = Connect-NLBaselineCA if (-not $connection) { Write-Error "Cannot connect to Microsoft 365" return } } # Export policies to AI folder Write-Host "Exporting policies to AI folder..." -ForegroundColor Yellow $rawPolicies = Get-AllConditionalAccessPolicies if (-not $rawPolicies -or $rawPolicies.Count -eq 0) { Write-Error "No policies found to export." return } Write-Host "Found: $($rawPolicies.Count) policies" -ForegroundColor Green # Export each policy to AI folder $exportedCount = 0 foreach ($policy in $rawPolicies) { $fileName = "$($policy.DisplayName).json" # Sanitize filename $fileName = $fileName -replace '[<>:"/\\|?*]', '_' $filePath = Join-Path $aiPoliciesPath $fileName # Convert policy to JSON and save $policyJson = $policy | ConvertTo-Json -Depth 10 $policyJson | Out-File -FilePath $filePath -Encoding UTF8 $exportedCount++ Write-Host " Exported: $fileName" -ForegroundColor Gray } Write-Host "" Write-Host "Export completed: $exportedCount policies saved to $aiPoliciesPath" -ForegroundColor Green Write-Host "" # Load policies from AI folder for analysis $policyFiles = Get-ChildItem -Path $aiPoliciesPath -Filter "*.json" -File if (-not $policyFiles) { Write-Error "No policy files found in $aiPoliciesPath" return } Write-Host "Analyzing $($policyFiles.Count) policies..." -ForegroundColor Yellow # Load all policies from AI folder $policies = @() foreach ($file in $policyFiles) { try { $policy = Get-Content $file.FullName | ConvertFrom-Json $policies += $policy } catch { Write-Warning "Could not load policy: $($file.Name)" } } if ($policies.Count -eq 0) { Write-Error "No valid policies found" return } # Prepare analysis with multiple AI agents Write-Host "Performing comprehensive AI analysis with specialist agents..." -ForegroundColor Yellow Write-Host "" $analysis = Invoke-AISecurityAnalysis -Policies $policies -AIConfig $aiConfig -StoragePath $storagePath # Display results if ($Host.UI.RawUI) { try { Clear-Host } catch { Write-Host "`n`n`n" } } Write-Host "========================================" -ForegroundColor Cyan Write-Host " SECURITY ADVISORY REPORT" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan Write-Host "" Write-Host "Analysis date: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -ForegroundColor White Write-Host "Number of policies analyzed: $($policies.Count)" -ForegroundColor White if ($analysis.RiskScore -gt 0) { $riskColor = if ($analysis.RiskScore -ge 70) { "Red" } elseif ($analysis.RiskScore -ge 40) { "Yellow" } else { "Green" } Write-Host "Overall Risk Score: $($analysis.RiskScore)/100" -ForegroundColor $riskColor } Write-Host "" # Display overall assessment if ($analysis.OverallAssessment) { Write-Host "========================================" -ForegroundColor Cyan Write-Host " OVERALL ASSESSMENT" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan Write-Host $analysis.OverallAssessment -ForegroundColor White Write-Host "" } # Display gaps if ($analysis.OverallGaps -and $analysis.OverallGaps.Count -gt 0) { Write-Host "========================================" -ForegroundColor Red Write-Host " IDENTIFIED SECURITY GAPS" -ForegroundColor Red Write-Host "========================================" -ForegroundColor Red for ($i = 0; $i -lt $analysis.OverallGaps.Count; $i++) { Write-Host " $($i + 1). $($analysis.OverallGaps[$i])" -ForegroundColor Yellow } Write-Host "" } # Display top recommendations if ($analysis.OverallRecommendations -and $analysis.OverallRecommendations.Count -gt 0) { Write-Host "========================================" -ForegroundColor Green Write-Host " TOP RECOMMENDATIONS" -ForegroundColor Green Write-Host "========================================" -ForegroundColor Green $topRecs = $analysis.OverallRecommendations | Select-Object -First 10 for ($i = 0; $i -lt $topRecs.Count; $i++) { Write-Host " $($i + 1). $($topRecs[$i])" -ForegroundColor White } Write-Host "" } # Display per-policy analysis summary if ($analysis.PolicyAnalysis -and $analysis.PolicyAnalysis.Count -gt 0) { Write-Host "========================================" -ForegroundColor Cyan Write-Host " PER-POLICY ANALYSIS SUMMARY" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan Write-Host "" Write-Host "Detailed analysis available for each policy:" -ForegroundColor Gray foreach ($policyAnalysis in $analysis.PolicyAnalysis) { Write-Host "" Write-Host "Policy: $($policyAnalysis.PolicyName)" -ForegroundColor Yellow Write-Host " State: $($policyAnalysis.State)" -ForegroundColor $(if ($policyAnalysis.State -eq "enabled") { "Green" } else { "Yellow" }) if ($policyAnalysis.Analysis) { $analysisLines = ($policyAnalysis.Analysis -split "`n" | Where-Object { $_.Trim() -ne "" }) | Select-Object -First 5 foreach ($line in $analysisLines) { Write-Host " $($line.Trim())" -ForegroundColor Gray } if (($policyAnalysis.Analysis -split "`n").Count -gt 5) { Write-Host " ... (see detailed logs for full analysis)" -ForegroundColor DarkGray } } } Write-Host "" } # Display agent results summary if ($analysis.AgentResults) { Write-Host "========================================" -ForegroundColor Cyan Write-Host " SPECIALIST AGENT ANALYSIS" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan Write-Host "" Write-Host "The following specialist agents have completed analysis:" -ForegroundColor Gray if ($analysis.AgentResults.GapAnalysis) { Write-Host " - Gap Analysis Specialist: $($analysis.AgentResults.GapAnalysis.Count) gaps identified" -ForegroundColor White } if ($analysis.AgentResults.PolicyCompliance) { Write-Host " - Policy Compliance Specialist: Analysis completed" -ForegroundColor White } if ($analysis.AgentResults.BaselineCoverage) { Write-Host " - Baseline Coverage Specialist: Coverage analysis completed" -ForegroundColor White } if ($analysis.AgentResults.SecurityBestPractices) { Write-Host " - Security Best Practices Specialist: Recommendations provided" -ForegroundColor White } if ($analysis.AgentResults.RiskAssessment) { Write-Host " - Risk Assessment Specialist: Risk analysis completed" -ForegroundColor White } if ($analysis.AgentResults.Reviewer) { Write-Host " - Reviewer Agent: Validation and improvement completed" -ForegroundColor White if ($analysis.QualityScore -gt 0) { Write-Host " Quality Score: $($analysis.QualityScore)/10" -ForegroundColor $(if ($analysis.QualityScore -ge 8) { "Green" } elseif ($analysis.QualityScore -ge 6) { "Yellow" } else { "Red" }) } } if ($analysis.UsedChunking) { Write-Host " - Chunking: Used to avoid rate limits" -ForegroundColor Gray } Write-Host "" } # Display baseline coverage info if ($analysis.BaselineCoverage) { Write-Host "========================================" -ForegroundColor Cyan Write-Host " BASELINE COVERAGE" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan Write-Host "" Write-Host "See detailed logs for baseline coverage analysis" -ForegroundColor Gray Write-Host "" } # Save comprehensive report $reportPath = Join-Path $storagePath "security-advisory-$(Get-Date -Format 'yyyyMMdd-HHmmss').json" $analysis | ConvertTo-Json -Depth 10 | Out-File -FilePath $reportPath -Encoding UTF8 Write-Host "========================================" -ForegroundColor Green Write-Host " REPORTS SAVED" -ForegroundColor Green Write-Host "========================================" -ForegroundColor Green Write-Host "Main report: $reportPath" -ForegroundColor White # Check if detailed logs were created $logsPath = Join-Path $storagePath "SecurityAnalysis" if (Test-Path $logsPath) { $latestLog = Get-ChildItem -Path $logsPath -Directory | Sort-Object LastWriteTime -Descending | Select-Object -First 1 if ($latestLog) { Write-Host "Detailed logs: $($latestLog.FullName)" -ForegroundColor White Write-Host " - Individual agent analyses" -ForegroundColor Gray Write-Host " - Per-policy detailed analysis" -ForegroundColor Gray Write-Host " - Complete analysis summary" -ForegroundColor Gray } } Write-Host "" } catch { Write-Error "Error generating Security Advisory: $_" } } |