###-----------------------------------------------------------------------------### ### SVS TaskGate Launcher ###-----------------------------------------------------------------------------### # 1) GLOBAL LOG CACHE if (-not $Global:LogCache -or -not ($Global:LogCache -is [System.Collections.ArrayList])) { $Global:LogCache = New-Object System.Collections.ArrayList } #region Write-LogHybrid if (-not (Get-Command Write-Log -ErrorAction SilentlyContinue)) { function Write-LogHelper { param( [string]$Message, [ValidateSet("Info","Warning","Error","Success","General")] [string]$Level = "Info", [string]$TaskCategory = "GeneralTask", [switch]$LogToEvent, [string]$EventSource = "SVSMSP_Module", [string]$EventLog = "Application" ) $EventID = switch($Level){ "Info" {1000}; "Warning"{2000}; "Error"{3000}; "Success"{4000}; default{1000} } $Icon = switch($Level){ "Info" { [char]0x1F4CB } "Warning" { [char]0x26A0 } "Error" { [char]0x274C } "Success" { [char]0x2705 } default { [char]0x1F4E6 } } $entry = [PSCustomObject]@{ Timestamp = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") Level = $Level Message = "$Icon [$Level] [$TaskCategory] $Message (Event ID: $EventID)" } [void]$Global:LogCache.Add($entry) if ($LogToEvent) { try { if (-not (Get-EventLog -LogName $EventLog -Source $EventSource -ErrorAction SilentlyContinue)) { New-EventLog -LogName $EventLog -Source $EventSource -ErrorAction SilentlyContinue } Write-EventLog -LogName $EventLog -Source $EventSource ` -EntryType $Level -EventId $EventID -Message $Message } catch { Write-Host "⚠ Failed writing to EventLog: $($_.Exception.Message)" -ForegroundColor Yellow } } } function Write-LogHybrid { param($Message,$Level,$TaskCategory,$LogToEvent) Write-LogHelper -Message $Message -Level $Level -TaskCategory $TaskCategory -LogToEvent:$LogToEvent } } else { function Write-LogHybrid { param($Message,$Level,$TaskCategory,$LogToEvent) Write-Log -Message $Message -Level $Level -TaskCategory $TaskCategory -LogToEvent:$LogToEvent } } Write-LogHybrid -Message "Starting SVS TaskGate" -Level Info -TaskCategory Startup -LogToEvent #region Helpers for DattoRMM, LastPass, SVS Module… # (Insert your existing Install-DattoRMM-Helper, LastPass and Install-SVSMSP functions here.) #endregion #region HTTP Listener Setup $listener = New-Object System.Net.HttpListener $listener.Prefixes.Add("http://localhost:8081/") $listener.Start() Write-LogHybrid -Message "Listener started on http://localhost:8081/" -Level Info -TaskCategory Listener #endregion #region HTML UI & CSS function GetHtmlContent { @" SVS TaskGate
SVS Logo

On-Boarding

…your original onboarding controls…

Apply Tweaks



Install SVS Apps

Winget Apps


Browser Extensions


"@ } #endregion # 3) LAUNCH THE UI Start-Process "msedge.exe" -ArgumentList "--app=http://localhost:8081/" #region 4) ROUTE HANDLING try { while ($listener.IsListening) { $ctx = $listener.GetContext() $req = $ctx.Request $res = $ctx.Response switch ($req.Url.AbsolutePath) { "/" { $html = GetHtmlContent $bytes = [Text.Encoding]::UTF8.GetBytes($html) $res.ContentType = "text/html" $res.ContentLength64 = $bytes.Length $res.OutputStream.Write($bytes,0,$bytes.Length) $res.OutputStream.Close() } "/runTweaks" { if ($req.HttpMethod -eq "POST") { $body = (New-Object IO.StreamReader $req.InputStream).ReadToEnd() | ConvertFrom-Json Write-LogHybrid -Message "Tweaks: $($body.tweaks -join ', ')" -Level Info -TaskCategory Tweaks # TODO: call your actual tweak functions here... $res.StatusCode = 200 $res.OutputStream.Write(([Text.Encoding]::UTF8.GetBytes("OK")),0,2) } } "/installSVSApps" { if ($req.HttpMethod -eq "POST") { $data = (New-Object IO.StreamReader $req.InputStream).ReadToEnd() | ConvertFrom-Json Write-LogHybrid -Message "Winget: $($data.winget -join ', ')" -Level Info -TaskCategory "SVSApps" Write-LogHybrid -Message "Extensions: $($data.extensions -join ', ')" -Level Info -TaskCategory "SVSApps" # TODO: invoke your winget & extension helpers here... $res.StatusCode = 200 $res.OutputStream.Write(([Text.Encoding]::UTF8.GetBytes("OK")),0,2) } } "/quit" { $res.StatusCode = 200 $res.OutputStream.Write(([Text.Encoding]::UTF8.GetBytes("bye")),0,3) $listener.Stop() break } default { $res.StatusCode = 404 $res.OutputStream.Write(([Text.Encoding]::UTF8.GetBytes("Not Found")),0,9) } } } } finally { if ($listener) { Write-LogHybrid -Message "Stopping listener" -Level Info -TaskCategory Listener $listener.Stop(); $listener.Close() } }