Private/Logging/Write-PWSHCertutilLog.ps1
|
function Write-PWSHCertutilLog { <# .SYNOPSIS Writes a log entry to the configured logging destination (file or Windows Event Log). .DESCRIPTION Central logging entry point called by every public cmdlet. Reads and normalizes the Logging section of the configuration, filters by MinimumLevel, and dispatches to Write-FileLogEntry or Write-EventLogEntry depending on Mode. Every entry is stamped with the Windows identity of the user running the command, so audit trails can always be linked back to who ran the action — not just what CA/profile it targeted. When -BoundParameters is supplied, its keys/values are appended to the message with Credential/Password/Secret/Token-named parameters redacted, so secrets never reach a log file or the Windows Event Log. Callers typically pass this only on the Debug-level entry-point log for each cmdlet invocation. No-ops silently when logging is disabled (Logging.Enabled = $false, the default for configs that predate this feature) or when Level is below the configured MinimumLevel. Never throws — a logging failure must never break the cmdlet's actual certutil/certreq work. .PARAMETER Config The parsed configuration object returned by Read-ConfigFile. .PARAMETER Level Severity of this entry: Debug, Information, Warning, or Error. .PARAMETER Message The log message. .PARAMETER CmdletName Name of the calling cmdlet, e.g. $MyInvocation.MyCommand.Name. .PARAMETER ProfileName Optional. The config profile involved in this action. .PARAMETER CAServer Optional. The CA server involved in this action. .PARAMETER BoundParameters Optional. $PSBoundParameters of the calling cmdlet; appended to the message with sensitive values redacted. .EXAMPLE Write-PWSHCertutilLog -Config $config -Level Debug -CmdletName $MyInvocation.MyCommand.Name -Message 'Cmdlet invoked' -BoundParameters $PSBoundParameters Logs cmdlet entry with its bound parameters (secrets redacted) at Debug level. .EXAMPLE Write-PWSHCertutilLog -Config $config -Level Information -CmdletName 'Get-PWSHCertutilIssuedCerts' -ProfileName 'prod-pki' -CAServer 'ca01.corp.local' -Message 'Retrieved 12 issued certificate(s)' Logs a one-line summary of a successful operation. #> [CmdletBinding()] param( [Parameter(Mandatory)] [PSCustomObject] $Config, [Parameter(Mandatory)] [ValidateSet('Debug', 'Information', 'Warning', 'Error')] [string] $Level, [Parameter(Mandatory)] [string] $Message, [Parameter(Mandatory)] [string] $CmdletName, [Parameter()] [string] $ProfileName, [Parameter()] [string] $CAServer, [Parameter()] [hashtable] $BoundParameters ) try { $loggingConfig = Get-LoggingConfig -Config $Config if (-not $loggingConfig.Enabled) { return } $minimumSeverity = $script:LogLevelSeverity[$loggingConfig.MinimumLevel] $entrySeverity = $script:LogLevelSeverity[$Level] if ($entrySeverity -lt $minimumSeverity) { return } $fullMessage = $Message if ($BoundParameters) { $redacted = foreach ($key in ($BoundParameters.Keys | Sort-Object)) { if ($key -match 'Credential|Password|Secret|Token') { "$key=<redacted>" } else { "$key=$($BoundParameters[$key])" } } $fullMessage = "$Message ($($redacted -join '; '))" } $entry = [PSCustomObject]@{ Timestamp = Get-Date Level = $Level UserName = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name CmdletName = $CmdletName ProfileName = $ProfileName CAServer = $CAServer Message = $fullMessage } if ($loggingConfig.Mode -eq 'EventLog') { Write-EventLogEntry -EventLog $loggingConfig.EventLog -Entry $entry } else { Write-FileLogEntry -File $loggingConfig.File -Entry $entry } } catch { if (-not $script:LoggingSinkFailed) { $script:LoggingSinkFailed = $true Write-Warning "Posh-Certutil logging failed and will be skipped for the rest of this session: $_" } } } |