Common/SecurityConfigHelper.ps1
|
<#
.SYNOPSIS Shared helpers for security-config collectors. .DESCRIPTION Provides the standard Add-SecuritySetting and Export-SecurityConfigReport functions used by all security-config collectors (EXO, Entra, Defender, SharePoint, Teams, Intune, Forms, Compliance, DNS). Centralizes the output contract, CheckId sub-numbering, progress tracking, and CSV export logic that was previously duplicated in each collector. Dot-source this file at the top of each security-config collector: . "$PSScriptRoot\..\Common\SecurityConfigHelper.ps1" .NOTES Author: Daren9m #> function Initialize-SecurityConfig { <# .SYNOPSIS Creates the standard settings collection and CheckId counter for a security-config collector. .OUTPUTS Hashtable with Settings (List[PSCustomObject]) and CheckIdCounter (hashtable). .EXAMPLE $ctx = Initialize-SecurityConfig $settings = $ctx.Settings $checkIdCounter = $ctx.CheckIdCounter #> [CmdletBinding()] [OutputType([hashtable])] param() @{ Settings = [System.Collections.Generic.List[PSCustomObject]]::new() CheckIdCounter = @{} } } function Add-SecuritySetting { <# .SYNOPSIS Adds a security configuration finding to the collector's settings list. .DESCRIPTION Standard output contract for all security-config collectors. Handles CheckId sub-numbering (e.g., EXO-AUTH-001 becomes EXO-AUTH-001.1, EXO-AUTH-001.2) and invokes real-time progress tracking when available. .PARAMETER Settings The List[PSCustomObject] collection to add the finding to. .PARAMETER CheckIdCounter Hashtable tracking sub-number counts per base CheckId. .PARAMETER Category Logical grouping for the setting (e.g., 'Authentication', 'External Sharing'). .PARAMETER Setting Human-readable name of the setting being checked. .PARAMETER CurrentValue The actual value found in the tenant. .PARAMETER RecommendedValue The expected/recommended value per the benchmark. .PARAMETER Status Assessment result: Pass, Fail, Warning, Review, or Info. .PARAMETER CheckId Registry check identifier (e.g., 'EXO-AUTH-001'). Sub-numbered automatically. .PARAMETER Remediation Guidance for fixing a non-passing result. #> [CmdletBinding()] param( [Parameter(Mandatory)] [AllowEmptyCollection()] [System.Collections.Generic.List[PSCustomObject]]$Settings, [Parameter(Mandatory)] [AllowEmptyCollection()] [hashtable]$CheckIdCounter, [Parameter(Mandatory)] [string]$Category, [Parameter(Mandatory)] [string]$Setting, [Parameter(Mandatory)] [AllowEmptyString()] [string]$CurrentValue, [Parameter(Mandatory)] [AllowEmptyString()] [string]$RecommendedValue, [Parameter(Mandatory)] [ValidateSet('Pass', 'Fail', 'Warning', 'Review', 'Info', 'Unknown')] [string]$Status, [Parameter()] [string]$CheckId = '', [Parameter()] [string]$Remediation = '' ) # Auto-generate sub-numbered CheckId for individual setting traceability $subCheckId = $CheckId if ($CheckId) { if (-not $CheckIdCounter.ContainsKey($CheckId)) { $CheckIdCounter[$CheckId] = 0 } $CheckIdCounter[$CheckId]++ $subCheckId = "$CheckId.$($CheckIdCounter[$CheckId])" } $Settings.Add([PSCustomObject]@{ Category = $Category Setting = $Setting CurrentValue = $CurrentValue RecommendedValue = $RecommendedValue Status = $Status CheckId = $subCheckId Remediation = $Remediation }) # Invoke real-time progress tracking if available (set up by Show-CheckProgress.ps1) if ($CheckId -and (Get-Command -Name Update-CheckProgress -ErrorAction SilentlyContinue)) { Update-CheckProgress -CheckId $subCheckId -Setting $Setting -Status $Status } } function Export-SecurityConfigReport { <# .SYNOPSIS Exports security-config settings to CSV or pipeline. .DESCRIPTION Standard output handler for all security-config collectors. Writes to CSV when OutputPath is provided, otherwise returns objects to the pipeline. .PARAMETER Settings The collected settings list. .PARAMETER OutputPath Optional CSV file path. If omitted, objects are written to the pipeline. .PARAMETER ServiceLabel Display name for log messages (e.g., 'Exchange Online', 'Entra ID'). #> [CmdletBinding()] param( [Parameter(Mandatory)] [object[]]$Settings, [Parameter()] [string]$OutputPath, [Parameter(Mandatory)] [string]$ServiceLabel ) $report = @($Settings) Write-Verbose "Collected $($report.Count) $ServiceLabel security configuration settings" if ($OutputPath) { $report | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8 Write-Output "Exported $ServiceLabel security config ($($report.Count) settings) to $OutputPath" } else { Write-Output $report } } |