Public/Invoke-CertificateAudit.ps1
|
function Invoke-CertificateAudit { <# .SYNOPSIS Orchestrates a full certificate lifecycle audit across one or more servers. .DESCRIPTION Runs all audit functions (Get-ExpiringCertificates, Get-CertificateStoreReport, Get-WeakCertificateReport, and optionally Get-IISCertificateReport), compiles the results into a color-coded HTML dashboard report, and optionally emails it to a distribution list. Designed to be scheduled via Task Scheduler for continuous monitoring. .PARAMETER ComputerName One or more computer names to audit. Defaults to localhost. .PARAMETER DaysWarning Number of days before expiration to flag as WARNING. Defaults to 30. .PARAMETER DaysCritical Number of days before expiration to flag as CRITICAL. Defaults to 7. .PARAMETER OutputPath Directory where the HTML report is saved. Defaults to the current directory. The report filename is generated automatically with a timestamp. .PARAMETER IncludeIIS When specified, also scans IIS HTTPS bindings on each target computer. .PARAMETER SendEmail When specified, sends the completed report via email. Requires -SmtpServer, -EmailTo, and -EmailFrom. .PARAMETER SmtpServer SMTP relay server for email delivery. .PARAMETER EmailTo Recipient email address(es). .PARAMETER EmailFrom Sender email address. .EXAMPLE Invoke-CertificateAudit Audits the local machine with default thresholds and saves a report to the current directory. .EXAMPLE Invoke-CertificateAudit -ComputerName Web01,Web02,DC01 -IncludeIIS -OutputPath C:\Reports Audits three servers including IIS bindings and saves the report. .EXAMPLE Invoke-CertificateAudit -ComputerName Web01 -SendEmail -SmtpServer mail.contoso.com -EmailTo ops@contoso.com -EmailFrom certs@contoso.com Audits Web01 and emails the report. .OUTPUTS System.IO.FileInfo - the generated HTML report file. #> [CmdletBinding()] param( [Parameter()] [string[]]$ComputerName = @('localhost'), [Parameter()] [int]$DaysWarning = 30, [Parameter()] [int]$DaysCritical = 7, [Parameter()] [string]$OutputPath = '.', [Parameter()] [switch]$IncludeIIS, [Parameter()] [switch]$SendEmail, [Parameter()] [string]$SmtpServer, [Parameter()] [string[]]$EmailTo, [Parameter()] [string]$EmailFrom ) begin { # Validate email parameters if -SendEmail is requested if ($SendEmail) { $missing = @() if (-not $SmtpServer) { $missing += '-SmtpServer' } if (-not $EmailTo) { $missing += '-EmailTo' } if (-not $EmailFrom) { $missing += '-EmailFrom' } if ($missing.Count -gt 0) { throw "SendEmail requires: $($missing -join ', ')" } } # Ensure output directory exists if (-not (Test-Path $OutputPath)) { Write-Verbose "Creating output directory: $OutputPath" New-Item -Path $OutputPath -ItemType Directory -Force | Out-Null } } process { $timestamp = Get-Date -Format 'yyyyMMdd-HHmmss' $reportFile = Join-Path $OutputPath "CertAudit-$timestamp.html" Write-Verbose "Starting certificate audit against: $($ComputerName -join ', ')" Write-Verbose "Thresholds - Warning: $DaysWarning days, Critical: $DaysCritical days" # ------------------------------------------------------------------ # 1. Expiring certificates # ------------------------------------------------------------------ Write-Verbose 'Phase 1 - Scanning for expiring certificates' $expiringCerts = @() try { $expiringCerts = Get-ExpiringCertificates -ComputerName $ComputerName ` -DaysUntilExpiration $DaysWarning ` -ErrorAction Stop } catch { Write-Warning "Expiring certificate scan failed: $_" } # ------------------------------------------------------------------ # 2. Full store inventory # ------------------------------------------------------------------ Write-Verbose 'Phase 2 - Building certificate store inventory' $storeReport = @() try { $storeReport = Get-CertificateStoreReport -ComputerName $ComputerName ` -IncludeExpired ` -ErrorAction Stop } catch { Write-Warning "Store inventory failed: $_" } # ------------------------------------------------------------------ # 3. Weak certificate detection # ------------------------------------------------------------------ Write-Verbose 'Phase 3 - Scanning for weak certificates' $weakCerts = @() try { $weakCerts = Get-WeakCertificateReport -ComputerName $ComputerName ` -ErrorAction Stop } catch { Write-Warning "Weak certificate scan failed: $_" } # ------------------------------------------------------------------ # 4. IIS bindings (optional) # ------------------------------------------------------------------ $iisCerts = @() if ($IncludeIIS) { Write-Verbose 'Phase 4 - Scanning IIS bindings' try { $iisCerts = Get-IISCertificateReport -ComputerName $ComputerName ` -ErrorAction Stop } catch { Write-Warning "IIS binding scan failed: $_" } } # ------------------------------------------------------------------ # 5. Summary counts # ------------------------------------------------------------------ $allFindings = @($expiringCerts) + @($iisCerts) $expiredCount = @($allFindings | Where-Object Finding -eq 'EXPIRED').Count $criticalCount = @($allFindings | Where-Object Finding -eq 'CRITICAL').Count $warningCount = @($allFindings | Where-Object Finding -eq 'WARNING').Count $okCount = @($allFindings | Where-Object Finding -eq 'OK').Count $weakCount = @($weakCerts).Count $totalScanned = @($storeReport).Count $summaryData = [PSCustomObject]@{ TotalScanned = $totalScanned Expired = $expiredCount Critical = $criticalCount Warning = $warningCount OK = $okCount WeakCrypto = $weakCount Computers = $ComputerName -join ', ' ReportTime = Get-Date -Format 'yyyy-MM-dd HH:mm:ss' } # ------------------------------------------------------------------ # 6. Generate HTML dashboard # ------------------------------------------------------------------ Write-Verbose 'Generating HTML dashboard' try { New-HtmlDashboard -SummaryData $summaryData ` -ExpiringCerts $expiringCerts ` -WeakCerts $weakCerts ` -IISCerts $iisCerts ` -StoreReport $storeReport ` -OutputPath $reportFile } catch { Write-Error "Failed to generate HTML report: $_" return } Write-Verbose "Report saved to $reportFile" # ------------------------------------------------------------------ # 7. Email delivery (optional) # ------------------------------------------------------------------ if ($SendEmail) { Write-Verbose "Sending report to $($EmailTo -join ', ')" try { $subject = 'Certificate Audit - ' + "$expiredCount expired, $criticalCount critical, $warningCount warning - " + (Get-Date -Format 'yyyy-MM-dd') Send-AuditReport -ReportPath $reportFile ` -SmtpServer $SmtpServer ` -To $EmailTo ` -From $EmailFrom ` -Subject $subject Write-Verbose 'Email sent successfully.' } catch { Write-Warning "Failed to send email: $_" } } # Return the report file object Get-Item $reportFile } end { Write-Verbose 'Invoke-CertificateAudit complete.' } } |