Private/ConvertTo-MDEWordReport.ps1
|
function ConvertTo-MDEWordReport { <# .SYNOPSIS Generates a Word (DOCX) validation report using the PSWriteWord module. .DESCRIPTION Takes the validation results array and report metadata and produces a formatted Word document with a title page, summary table, and per-category result tables. Requires the PSWriteWord module (Install-Module -Name PSWriteWord). No Microsoft Office installation needed. .PARAMETER Results The array of validation result objects produced by Test-MDEConfiguration. .PARAMETER OutputPath The full path for the output DOCX file. .PARAMETER ComputerName The computer name shown in the report header. .PARAMETER OSInfo The operating system description shown in the report header. .PARAMETER ManagedByStatus The management status shown in the report header. .PARAMETER OnboardingStatus The MDE onboarding status shown in the report header. .OUTPUTS [string] The path to the generated DOCX file. #> [CmdletBinding()] [OutputType([string])] param( [Parameter(Mandatory)] [AllowEmptyCollection()] [AllowNull()] [object[]]$Results, [Parameter(Mandatory)] [string]$OutputPath, [Parameter(Mandatory)] [AllowEmptyString()] [string]$ComputerName, [Parameter(Mandatory)] [AllowEmptyString()] [string]$OSInfo, [Parameter(Mandatory)] [AllowEmptyString()] [string]$ManagedByStatus, [Parameter(Mandatory)] [AllowEmptyString()] [string]$OnboardingStatus ) Import-Module PSWriteWord -ErrorAction Stop # Ensure output directory exists $outputDirectory = Split-Path -Path $OutputPath -Parent if (-not [string]::IsNullOrEmpty($outputDirectory) -and -not (Test-Path -Path $outputDirectory)) { New-Item -Path $outputDirectory -ItemType Directory -Force | Out-Null } # Create a new Word document $wordDocument = New-WordDocument -FilePath $OutputPath # --- Title --- Add-WordText -WordDocument $wordDocument -Text 'Microsoft Defender for Endpoint' ` -FontSize 24 -FontFamily 'Segoe UI' -Bold $true -Color '0f3460' Add-WordText -WordDocument $wordDocument -Text 'Configuration Validation Report' ` -FontSize 16 -FontFamily 'Segoe UI' -Color '4a5568' Add-WordText -WordDocument $wordDocument -Text '' -FontSize 8 # --- Metadata Table --- $metaData = @( @('Computer', $ComputerName), @('Operating System', $OSInfo), @('Managed By', $ManagedByStatus), @('MDE Onboarding', $OnboardingStatus), @('Generated', (Get-Date -Format 'yyyy-MM-dd HH:mm:ss')) ) Add-WordTable -WordDocument $wordDocument -DataTable $metaData -Design 'LightShading' ` -AutoFit 'Window' Add-WordText -WordDocument $wordDocument -Text '' -FontSize 8 # --- Summary --- $passCount = @($Results | Where-Object { $_.Status -eq 'Pass' }).Count $failCount = @($Results | Where-Object { $_.Status -eq 'Fail' }).Count $warnCount = @($Results | Where-Object { $_.Status -eq 'Warning' }).Count $infoCount = @($Results | Where-Object { $_.Status -eq 'Info' }).Count $totalCount = @($Results).Count Add-WordText -WordDocument $wordDocument -Text 'Summary' ` -FontSize 14 -FontFamily 'Segoe UI' -Bold $true -Color '0f3460' $summaryTable = @( @('Total', 'Passed', 'Failed', 'Warnings', 'Informational'), @($totalCount, $passCount, $failCount, $warnCount, $infoCount) ) Add-WordTable -WordDocument $wordDocument -DataTable $summaryTable -Design 'LightGrid' ` -AutoFit 'Window' Add-WordText -WordDocument $wordDocument -Text '' -FontSize 8 # --- Results by Category --- $knownSectionOrder = @( 'Device State', 'Protection Settings', 'Onboarding', 'Network Protection', 'ASR Rules', 'Tamper Protection', 'Exclusion Settings' ) $grouped = [ordered]@{} foreach ($r in $Results) { $sec = if ([string]::IsNullOrEmpty($r.Category)) { 'General / Other' } else { $r.Category } if (-not $grouped.Contains($sec)) { $grouped[$sec] = New-Object System.Collections.Generic.List[object] } $grouped[$sec].Add($r) } $sectionOrder = New-Object System.Collections.Generic.List[string] foreach ($s in $knownSectionOrder) { if ($grouped.Contains($s)) { $sectionOrder.Add($s) } } foreach ($key in $grouped.Keys) { if ($knownSectionOrder -notcontains $key) { $sectionOrder.Add($key) } } foreach ($section in $sectionOrder) { $sectionResults = $grouped[$section] if ($sectionResults.Count -eq 0) { continue } Add-WordText -WordDocument $wordDocument -Text $section ` -FontSize 12 -FontFamily 'Segoe UI' -Bold $true -Color '0f3460' # Build table data: header + rows $tableData = @(, @('Test Name', 'Status', 'Expected', 'Actual', 'Recommendation')) foreach ($result in $sectionResults) { $actual = if ($result.PSObject.Properties.Name -contains 'ASRSummary' -and $result.ASRSummary) { $result.ASRSummary } else { $result.Message } $tableData += , @( $result.TestName, $result.Status, $(if ($result.Expected) { $result.Expected } else { '-' }), $actual, $(if ($result.Recommendation) { $result.Recommendation } else { '-' }) ) } Add-WordTable -WordDocument $wordDocument -DataTable $tableData -Design 'LightShading' ` -AutoFit 'Window' Add-WordText -WordDocument $wordDocument -Text '' -FontSize 6 } # Save the document Save-WordDocument -WordDocument $wordDocument return $OutputPath } |