4.4 KiB
logging.fallback.ps1
This file implements SAMY’s fallback logging functions used across the project.
It supports:
- Console logging (color-coded)
- In-memory log caching (for UI/diagnostics)
- Optional file logging (UTF-8 without BOM)
- Optional Windows Event Log logging, including:
- first-run creation of the log/source (when elevated)
- resolving “source bound to the wrong log” problems
Regions overview
Globals
What it does
- Initializes shared global state used by logging:
LogCache: anArrayListof log entries created during execution.EventSinkCache: aHashtablecaching resolved Event Log sinks so we do not repeatedly initialize/bind.
Why it exists
- Makes log output available to UI or post-run summaries.
- Prevents repeated Event Log setup attempts and repeated warnings.
Helpers: Formatting + File
What it does
Get-LogColor(Level): mapsInfo/Warning/Error/Success/Generalto console colors.Get-EventIdForLevel(Level, CustomEventID): returns default Event IDs by level unless overridden.Get-EventEntryTypeForLevel(Level): maps levels to Event Log entry types.Append-Utf8NoBomLine(Path, Line): appends a line to a file using UTF-8 without BOM.
Why it exists
- Keeps the main logging functions readable.
- Ensures runtime log files comply with the repository encoding rule (UTF-8 no BOM).
Helpers: Event Log Binding
Background Windows Event Log has a key constraint:
A Source can only be registered to one Log at a time.
Example:
- If source
SVMSP_Moduleis registered toApplication, you cannot write with:Write-EventLog -LogName "SVSMSP Events" -Source "SVMSP_Module"until that binding is repaired or avoided.
What it does
Test-IsAdmin(): checks if the current PowerShell session is elevated.Initialize-EventLogBinding(DesiredLog, DesiredSource, ConflictPolicy): returns an effective{ LogName, Source, IsAdmin }that is safe to use forWrite-EventLog.
ConflictPolicy
If DesiredSource exists but is bound to a different log, one of these policies applies:
-
Repair(default)- Removes the existing source registration from its current log
- Recreates it under
DesiredLog - Requires elevation
- Best when you want all SAMY logs in one custom log
-
Unique- Creates a new SAMY-specific source under
DesiredLog(e.g.,SVMSP_Module.SAMY,SVMSP_Module.SAMY2, etc.) - Does not delete anything
- Requires elevation to create the new source
- Best when you want no deletion / no rebinding risk
- Creates a new SAMY-specific source under
-
Follow- Uses whichever log the source is already bound to
- Never deletes anything
- May log to
Applicationif that’s where the source already exists - Best when you want maximum safety and minimum changes
Non-admin behavior If not elevated and the desired source does not exist, the code falls back to:
LogName = ApplicationSource = Windows PowerShell
This avoids trying to create custom Event Log sources without admin rights.
Public: Write-LogHelper
What it does This is the core fallback logger.
Always does:
- Writes a formatted message to console (with color)
- Adds an entry to
Global:LogCache
Optionally does:
- File logging (when
-LogFileis provided) - Event Log logging (when
-LogToEventis set)
Event Log caching To avoid repeating setup work, the function caches the resolved Event Log sink:
- Key format:
"$EventLog|$EventSource|$EventLogConflictPolicy" - Cached value includes:
Ready(boolean)LogName(effective log to write to)Source(effective source to write with)
Parameters that matter most
-Message: text to log-Level: affects console color, EventId, EntryType-TaskCategory: included in formatted message and event message-LogToEvent: enable/disable Event Log writes-EventLog,-EventSource: desired Event Log sink-EventLogConflictPolicy:Repair,Unique, orFollow
Public: Write-LogHybrid
What it does A wrapper for compatibility.
Behavior:
- If a preferred logger function
Write-Logexists, it calls that. - Otherwise it calls
Write-LogHelper.
Why it exists
- Lets SAMY swap logging implementations without changing all call sites.
Typical usage examples
Console only
Write-LogHybrid -Message "Starting SAMY" -Level Info -TaskCategory "Startup"