# SVS TaskGate: Self-contained PowerShell Task Runner UI (All-in-One Script) # ----- 1. TASK REGISTRY ----- $TaskRegistry = @{ Onboarding = @( @{ Key = "installSVSMSP"; Label = "Install SVSMSP Module"; Function = "Install-SVSMSP" } @{ Key = "installDattoRMM"; Label = "Install DattoRMM"; Function = "Install-DattoRMM" } @{ Key = "installCyberQP"; Label = "Install CyberQP"; Function = "Install-CyberQP" } ) Offboarding = @( @{ Key = "uninstallSVSMSP"; Label = "Uninstall SVSMSP Module"; Function = "Uninstall-SVSMSP" } @{ Key = "uninstallDattoRMM"; Label = "Uninstall DattoRMM"; Function = "Uninstall-DattoRMM" } @{ Key = "uninstallCyberQP"; Label = "Uninstall CyberQP"; Function = "Uninstall-CyberQP" } ) Tweaks = @( @{ Key = "setPowerPlan"; Label = "Set Power Plan"; Function = "Set-SVSPowerPlan" } @{ Key = "enableBitLocker"; Label = "Enable BitLocker"; Function = "Enable-BitLocker" } ) } # ----- 2. FUNCTION STUBS (Replace with real logic) ----- function Install-SVSMSP { Write-Host "Installing SVSMSP Module..." } function Install-DattoRMM { Write-Host "Installing DattoRMM..." } function Install-CyberQP { Write-Host "Installing CyberQP..." } function Uninstall-SVSMSP { Write-Host "Uninstalling SVSMSP Module..." } function Uninstall-DattoRMM { Write-Host "Uninstalling DattoRMM..." } function Uninstall-CyberQP { Write-Host "Uninstalling CyberQP..." } function Set-SVSPowerPlan { Write-Host "Setting SVS Power Plan..." } function Enable-BitLocker { Write-Host "Enabling BitLocker..." } # ----- 3. HTML UI GENERATOR ----- function Get-TasksHtml($group) { $html = "" foreach ($task in $TaskRegistry[$group]) { $html += "
`n" } return $html } $HtmlContent = @" SVS TaskGate

SVS TaskGate

Onboarding

$(Get-TasksHtml 'Onboarding')

Offboarding

$(Get-TasksHtml 'Offboarding')

Tweaks

$(Get-TasksHtml 'Tweaks')
"@ # ----- 4. HTTP LISTENER (Self-contained, single-file, no dependencies) ----- Add-Type -AssemblyName System.Net.HttpListener $listener = New-Object System.Net.HttpListener $listener.Prefixes.Add("http://localhost:8081/") $listener.Start() Write-Host "TaskGate listening at http://localhost:8081/" # Open browser to UI (Edge, fallback Chrome) try { Start-Process "msedge.exe" -ArgumentList "--app=http://localhost:8081/" } catch { Start-Process "chrome.exe" "http://localhost:8081/" } while ($listener.IsListening) { $context = $listener.GetContext() $req = $context.Request $res = $context.Response try { switch ($req.Url.AbsolutePath) { "/" { $bytes = [System.Text.Encoding]::UTF8.GetBytes($HtmlContent) $res.ContentType = "text/html" $res.ContentLength64 = $bytes.Length $res.OutputStream.Write($bytes, 0, $bytes.Length) $res.OutputStream.Close() } "/run-tasks" { if ($req.HttpMethod -ne "POST") { $res.StatusCode = 405 $res.OutputStream.Close() continue } $reader = New-Object IO.StreamReader $req.InputStream $body = $reader.ReadToEnd() | ConvertFrom-Json $group = $body.group $selectedKeys = $body.tasks $executed = @() foreach ($key in $selectedKeys) { $task = $TaskRegistry[$group] | Where-Object { $_.Key -eq $key } if ($task) { try { & $task.Function $executed += $task.Label } catch { $executed += "$($task.Label) (ERROR)" } } } $resp = @{ status = "OK"; executed = $executed } $bytes = [System.Text.Encoding]::UTF8.GetBytes(($resp | ConvertTo-Json)) $res.ContentType = "application/json" $res.ContentLength64 = $bytes.Length $res.OutputStream.Write($bytes, 0, $bytes.Length) $res.OutputStream.Close() } default { $res.StatusCode = 404 $bytes = [System.Text.Encoding]::UTF8.GetBytes("404 Not Found") $res.OutputStream.Write($bytes, 0, $bytes.Length) $res.OutputStream.Close() } } } catch { $res.StatusCode = 500 $err = "Error: $($_.Exception.Message)" $bytes = [System.Text.Encoding]::UTF8.GetBytes($err) $res.OutputStream.Write($bytes, 0, $bytes.Length) $res.OutputStream.Close() } }