# 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()
}
}