Public/Export-CISReport.ps1

function Export-CISReport {
    <#
    .SYNOPSIS
        Re-generates reports from a previously saved JSON scan result.

    .DESCRIPTION
        Takes a CIS benchmark JSON report file and generates HTML and/or CSV reports
        from it. Useful for regenerating reports without re-running the scan.

    .PARAMETER JsonPath
        Path to the previously saved JSON report file.

    .PARAMETER OutputDirectory
        Directory for generated reports.

    .PARAMETER OutputFormat
        Report format(s) to generate: 'HTML', 'CSV', or 'All'.

    .PARAMETER ReportName
        Base name for report files. Derived from JSON filename if not specified.

    .EXAMPLE
        Export-CISReport -JsonPath ./reports/CIS-Azure-v5.0.0_MySub_20260223.json

    .EXAMPLE
        Export-CISReport -JsonPath ./scan.json -OutputFormat HTML -OutputDirectory ./dashboards
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string]$JsonPath,

        [Parameter()]
        [string]$OutputDirectory,

        [Parameter()]
        [ValidateSet('HTML', 'CSV', 'SARIF', 'All')]
        [string[]]$OutputFormat = @('All'),

        [Parameter()]
        [string]$ReportName
    )

    if (-not (Test-Path $JsonPath)) {
        Write-Error "JSON file not found: $JsonPath"
        return
    }

    try {
        $jsonData = Get-Content -Path $JsonPath -Raw -Encoding UTF8 | ConvertFrom-Json
    }
    catch {
        Write-Error "Failed to parse JSON file '$JsonPath': $($_.Exception.Message)"
        return
    }

    if (-not $OutputDirectory) {
        $OutputDirectory = Split-Path $JsonPath -Parent
    }

    if (-not (Test-Path $OutputDirectory)) {
        New-Item -ItemType Directory -Path $OutputDirectory -Force | Out-Null
    }

    if (-not $ReportName) {
        $ReportName = [System.IO.Path]::GetFileNameWithoutExtension($JsonPath)
    }

    # Reconstruct metadata
    $metadata = @{
        SubscriptionName = $jsonData.subscriptionName
        SubscriptionId   = $jsonData.subscriptionId
        TenantId         = $jsonData.tenantId
        ScanTimestamp    = $jsonData.scanTimestamp
    }

    # Reconstruct results array
    $results = $jsonData.results | ForEach-Object {
        [PSCustomObject]@{
            PSTypeName       = 'CISBenchmarkResult'
            ControlId        = $_.controlId
            Title            = $_.title
            Status           = $_.status
            Severity         = $_.severity
            Section          = $_.section
            Subsection       = $_.subsection
            AssessmentStatus = $_.assessmentStatus
            ProfileLevel     = $_.profileLevel
            Description      = $_.description
            Details          = $_.details
            Remediation      = $_.remediation
            AffectedResources = if ($_.affectedResources) { @($_.affectedResources) } else { @() }
            TotalResources   = $_.totalResources
            PassedResources  = $_.passedResources
            FailedResources  = $_.failedResources
            References       = if ($_.references) { @($_.references) } else { @() }
            CISControls      = if ($_.cisControls) { @($_.cisControls) } else { @() }
            Timestamp        = $_.timestamp
        }
    }

    $formats = if ('All' -in $OutputFormat) { @('HTML', 'CSV', 'SARIF') } else { $OutputFormat }
    $reportPaths = @{}

    if ('HTML' -in $formats) {
        $htmlPath = Join-Path $OutputDirectory "$ReportName.html"
        Write-Host " Generating HTML report..." -ForegroundColor Yellow
        $reportPaths.HTML = New-CISHtmlReport -Results $results -OutputPath $htmlPath -Metadata $metadata
        Write-Host " HTML: $htmlPath" -ForegroundColor Green
    }

    if ('CSV' -in $formats) {
        $csvPath = Join-Path $OutputDirectory "$ReportName.csv"
        Write-Host " Generating CSV report..." -ForegroundColor Yellow
        $reportPaths.CSV = New-CISCsvReport -Results $results -OutputPath $csvPath -Metadata $metadata
        Write-Host " CSV: $csvPath" -ForegroundColor Green
    }

    if ('SARIF' -in $formats) {
        $sarifPath = Join-Path $OutputDirectory "$ReportName.sarif"
        Write-Host " Generating SARIF report..." -ForegroundColor Yellow
        $reportPaths.SARIF = New-CISSarifReport -Results $results -OutputPath $sarifPath -Metadata $metadata
        Write-Host " SARIF: $sarifPath" -ForegroundColor Green
    }

    return $reportPaths
}