diff --git a/testTaskGate.ps1 b/testTaskGate.ps1
index a76fc1f..0da32b9 100644
--- a/testTaskGate.ps1
+++ b/testTaskGate.ps1
@@ -1,310 +1,111 @@
-### To Modify as of January 27 2025
+###-----------------------------------------------------------------------------###
+### SVS TaskGate Launcher
+###-----------------------------------------------------------------------------###
-### let's start thinking about the write-log -TaskCategory "On-boarding" or "Off-boarding"
-### need RGB color codes from john, once we picked the RGBA colors
-### add the .NET silent install tweaks to toolkit
-### for the reg tweak need to do/undo function maybe it should have its own check box list
-### added offboard check boxes for DattoRMM, DattoDEB, RocketCyber, CyberQP, SVSHelpdesk and Splashtop
-### need to fix path in the uninstall-DattoEDR -
-####### ❌ [Error] [GeneralTask] Uninstallation command 'C:\Program Files\Infocyte\Agent\agent.exe' not found. (Event ID: 3000) - bad path
-
-# ---------------------------------------------------------------------------
-# 1) CREATE A GLOBAL LOG CACHE (NEW)
-# ---------------------------------------------------------------------------
+# 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-LogHelper
-if (-not (Get-Command -Name Write-Log -CommandType Function -ErrorAction SilentlyContinue)) {
+#region Write-LogHybrid
+if (-not (Get-Command Write-Log -ErrorAction SilentlyContinue)) {
function Write-LogHelper {
- param (
+ param(
[string]$Message,
- [ValidateSet("Info", "Warning", "Error", "Success", "General")]
+ [ValidateSet("Info","Warning","Error","Success","General")]
[string]$Level = "Info",
[string]$TaskCategory = "GeneralTask",
- [switch]$LogToEvent = $false,
+ [switch]$LogToEvent,
[string]$EventSource = "SVSMSP_Module",
- [string]$EventLog = "Application",
- [int]$CustomEventID
+ [string]$EventLog = "Application"
)
- $EventID = switch ($Level) {
- "Info" { 1000 }
- "Warning" { 2000 }
- "Error" { 3000 }
- "Success" { 4000 }
- "General" { 1000 }
+ $EventID = switch($Level){
+ "Info" {1000}; "Warning"{2000}; "Error"{3000}; "Success"{4000}; default{1000}
}
- $Icon = switch ($Level) {
- "Info" { [System.Char]::ConvertFromUtf32(0x1F4CB) }
- "Warning" { ([char]0x26A0) }
- "Error" { ([char]0x274C) }
- "Success" { ([char]0x2705) }
- "General" { ([char]0x1F4E6) }
+ $Icon = switch($Level){
+ "Info" { [char]0x1F4CB }
+ "Warning" { [char]0x26A0 }
+ "Error" { [char]0x274C }
+ "Success" { [char]0x2705 }
+ default { [char]0x1F4E6 }
}
- $logEntry = [PSCustomObject]@{
- Timestamp = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
- Level = $Level
- Message = "$Icon [$Level] [$TaskCategory] $Message (Event ID: $EventID)"
+ $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($logEntry)
+ [void]$Global:LogCache.Add($entry)
if ($LogToEvent) {
- $EntryType = switch ($Level) {
- "Info" { "Information" }
- "Warning" { "Warning" }
- "Error" { "Error" }
- default { "Information" }
- }
try {
if (-not (Get-EventLog -LogName $EventLog -Source $EventSource -ErrorAction SilentlyContinue)) {
New-EventLog -LogName $EventLog -Source $EventSource -ErrorAction SilentlyContinue
}
- $EventMessage = "TaskCategory: $TaskCategory | Message: $Message"
- Write-EventLog -LogName $EventLog -Source $EventSource -EntryType $EntryType -EventId $EventID -Message $EventMessage
- }
- catch {
- Write-Host "⚠ [Warning] [EventLog] Failed to write to Event Log: $($_.Exception.Message)" -ForegroundColor Yellow
+ 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 (
- [string]$Message,
- [ValidateSet("Info", "Warning", "Error", "Success", "General")]
- [string]$Level = "Info",
- [string]$TaskCategory = "GeneralTask",
- [switch]$LogToEvent = $false,
- [string]$EventSource = "SVSMSP_Module",
- [string]$EventLog = "Application",
- [int]$CustomEventID
- )
- Write-LogHelper -Message $Message -Level $Level -TaskCategory $TaskCategory `
- -LogToEvent:$LogToEvent -EventSource $EventSource -EventLog $EventLog `
- -CustomEventID $CustomEventID
+ 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
}
}
-else {
- function Write-LogHybrid {
- param (
- [string]$Message,
- [ValidateSet("Info", "Warning", "Error", "Success", "General")]
- [string]$Level = "Info",
- [string]$TaskCategory = "GeneralTask",
- [switch]$LogToEvent = $false,
- [string]$EventSource = "SVSMSP_Module",
- [string]$EventLog = "Application",
- [int]$CustomEventID
- )
- Write-Log -Message $Message -Level $Level -TaskCategory $TaskCategory `
- -LogToEvent:$LogToEvent -EventSource $EventSource -EventLog $EventLog `
- -CustomEventID $CustomEventID
- }
-}
-Write-LogHybrid -Message "Starting SVS TaskGate" -Level "Info" -TaskCategory "SVSTaskGate" -LogToEvent:$true
+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 Install-DattoRMM-Helper
-function Install-DattoRMM-Helper {
- param (
- [string]$ApiUrl,
- [string]$ApiKey,
- [string]$ApiSecretKey,
- [switch]$FetchSitesOnly,
- [string]$SiteName,
- [string]$SiteUID
- )
- if (-not $ApiUrl -or -not $ApiKey -or -not $ApiSecretKey) {
- Write-LogHybrid -Message "Missing required parameters. Please provide ApiUrl, ApiKey, and ApiSecretKey." -Level "Error" -LogToEvent
- return
- }
- [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
- Write-LogHybrid -Message "Fetching OAuth token..." -Level "Info"
- try {
- $securePassword = ConvertTo-SecureString -String 'public' -AsPlainText -Force
- $apiGenToken = Invoke-WebRequest -Credential (New-Object System.Management.Automation.PSCredential -ArgumentList ('public-client', $securePassword)) `
- -Uri ("{0}/auth/oauth/token" -f $ApiUrl) `
- -Method 'POST' `
- -ContentType 'application/x-www-form-urlencoded' `
- -Body ("grant_type=password&username={0}&password={1}" -f $ApiKey, $ApiSecretKey) `
- | ConvertFrom-Json
- $requestToken = $apiGenToken.access_token
- Write-LogHybrid -Message "OAuth token fetched successfully." -Level "Success" -LogToEvent
- } catch {
- Write-LogHybrid -Message "Failed to fetch OAuth token. Details: $($_.Exception.Message)" -Level "Error" -LogToEvent
- return
- }
- if ($FetchSitesOnly) {
- Write-Host "Fetching list of sites from the Datto RMM API..." -ForegroundColor Cyan
- try {
- $getSites = Invoke-WebRequest -Uri "$ApiUrl/api/v2/account/sites" -Method Get -Headers @{ "Authorization" = "Bearer $requestToken" } -ContentType "application/json"
- $sitesJson = $getSites.Content | ConvertFrom-Json
- $siteList = $sitesJson.sites | ForEach-Object {
- [PSCustomObject]@{ Name = $_.name; UID = $_.uid }
- }
- Write-Host "Successfully fetched list of sites." -ForegroundColor Green
- return $siteList
- }
- catch {
- Write-Host "Failed to fetch sites: $($_.Exception.Message)" -ForegroundColor Red
- return
- }
- }
-}
-#endregion
-
-#region LastPass Extensions
-function ForceInstall-LastPassChrome {
- $ExtensionID = "hdokiejnpimakedhajhdlcegeplioahd"
- $UpdateURL = "https://clients2.google.com/service/update2/crx"
- $RegPath = "HKLM:\SOFTWARE\Policies\Google\Chrome\ExtensionInstallForcelist"
- try {
- New-Item -Path (Split-Path $RegPath) -Force -ErrorAction SilentlyContinue | Out-Null
- New-Item -Path $RegPath -Force -ErrorAction SilentlyContinue | Out-Null
- Set-ItemProperty -Path $RegPath -Name "1" -Value "$ExtensionID;$UpdateURL" -ErrorAction Stop
- Write-Host "Configured LastPass Chrome extension."
- }
- catch {
- Write-Host "Failed Chrome config: $($_.Exception.Message)" -ForegroundColor Red
- }
-}
-function ForceInstall-LastPassEdge {
- $ExtensionID = "bbcinlkgjjkejfdpemiealijmmooekmp"
- $UpdateURL = "https://edge.microsoft.com/extensionwebstorebase/v1/crx"
- $RegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Edge\ExtensionInstallForcelist"
- try {
- New-Item -Path (Split-Path $RegPath) -Force -ErrorAction SilentlyContinue | Out-Null
- New-Item -Path $RegPath -Force -ErrorAction SilentlyContinue | Out-Null
- Set-ItemProperty -Path $RegPath -Name "1" -Value "$ExtensionID;$UpdateURL" -ErrorAction Stop
- Write-Host "Configured LastPass Edge extension."
- }
- catch {
- Write-Host "Failed Edge config: $($_.Exception.Message)" -ForegroundColor Red
- }
-}
-function Install-LastPassExtensions { param([switch]$Chrome,[switch]$Edge)
- if ($Chrome) { ForceInstall-LastPassChrome }
- if ($Edge) { ForceInstall-LastPassEdge }
-}
-#endregion
-
-#region SVS Module
-function Install-SVSMSP {
- param (
- [switch]$Cleanup,
- [switch]$InstallToolkit,
- [array]$AllModules = @(@{ModuleName="SVS_Toolkit"},@{ModuleName="SVSMSP"}),
- [string]$NewModuleName = "SVSMSP",
- [array]$AllRepositories = @(@{RepoName="SVS_Repo"},@{RepoName="SVS_Toolkit"}),
- [string]$NewRepositoryName = "SVS_Repo",
- [string]$NewRepositoryURL = "http://proget.svstools.ca:8083/nuget/SVS_Repo/",
- [string]$LogFilePath = "$env:SVSMSP\svstoolkit.log"
- )
- function Perform-Cleanup {
- Write-LogHybrid -Message "Cleanup mode enabled..." -Level Info -LogToEvent
- foreach ($m in $AllModules) {
- if (Get-Module -Name $m.ModuleName -ListAvailable) {
- Write-LogHybrid -Message "Removing $($m.ModuleName)..." -Level Warning -LogToEvent
- try { Uninstall-Module -Name $m.ModuleName -AllVersions -Force; Write-LogHybrid -Message "Removed $($m.ModuleName)" -Level Success -LogToEvent }
- catch { Write-LogHybrid -Message "Failed to remove $($m.ModuleName): $_" -Level Error -LogToEvent }
- }
- }
- foreach ($r in $AllRepositories) {
- if (Get-PSRepository -Name $r.RepoName -ErrorAction SilentlyContinue) {
- Write-LogHybrid -Message "Unregistering $($r.RepoName)..." -Level Warning -LogToEvent
- try { Unregister-PSRepository -Name $r.RepoName -ErrorAction Stop; Write-LogHybrid -Message "Unregistered $($r.RepoName)" -Level Success -LogToEvent }
- catch { Write-LogHybrid -Message "Failed to unregister $($r.RepoName): $_" -Level Error -LogToEvent }
- }
- }
- Write-LogHybrid -Message "Cleanup complete." -Level Success -LogToEvent
- }
- function Perform-ToolkitInstallation {
- Perform-Cleanup
- if ((Get-ExecutionPolicy -Scope LocalMachine) -ne "RemoteSigned") {
- Write-LogHybrid -Message "Setting execution policy to RemoteSigned..." -Level Warning -LogToEvent
- try { Set-ExecutionPolicy RemoteSigned -Scope LocalMachine -Force; Write-LogHybrid -Message "Policy set." -Level Success -LogToEvent }
- catch { Write-LogHybrid -Message "Failed to set policy: $_" -Level Error -LogToEvent; return }
- }
- Install-PackageProvider -Name NuGet -Force -Scope AllUsers -Confirm:$false
- if (-not (Get-PSRepository -Name $NewRepositoryName -ErrorAction SilentlyContinue)) {
- Write-LogHybrid -Message "Registering $NewRepositoryName..." -Level Info -LogToEvent
- try { Register-PSRepository -Name $NewRepositoryName -SourceLocation $NewRepositoryURL -InstallationPolicy Trusted; Write-LogHybrid -Message "Registered." -Level Success -LogToEvent }
- catch { Write-LogHybrid -Message "Register failed: $_" -Level Error -LogToEvent }
- }
- Write-LogHybrid -Message "Installing $NewModuleName..." -Level Info -LogToEvent
- try { Install-Module -Name $NewModuleName -Repository $NewRepositoryName -Scope AllUsers -Force; Write-LogHybrid -Message "Installed." -Level Success -LogToEvent }
- catch { Write-LogHybrid -Message "Install failed: $_" -Level Error -LogToEvent }
- }
- Write-LogHybrid -Message "Install-SVSMSP started." -Level Info -LogToEvent
- if ($Cleanup) { Perform-Cleanup; return }
- if ($InstallToolkit) { Perform-ToolkitInstallation; return }
- Perform-ToolkitInstallation
-}
-#endregion
#region HTTP Listener Setup
-try {
- $listener = New-Object System.Net.HttpListener
- $listener.Prefixes.Add("http://localhost:8081/")
- Write-LogHybrid -Message "Listener prefix added." -Level Info
- $listener.Start()
- Write-LogHybrid -Message "Listener started." -Level Info
-} catch {
- Write-LogHybrid -Message "Listener init error: $($_.Exception.Message)" -Level Error
- throw
-}
+$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
-function Get-N8nWebhookData {
- param ([string]$AuthHeaderValue)
- $url = "https://automate.svstools.ca/webhook/svsmspkit"
- $headers = @{ "SVSMSPKit" = $AuthHeaderValue }
- try {
- $resp = Invoke-RestMethod -Uri $url -Headers $headers -Method Get
- foreach ($prop in $resp.PSObject.Properties) {
- Set-Variable -Name $prop.Name -Value $prop.Value -Scope Global
- }
- return $resp
- } catch {
- Write-Host "Webhook GET error: $($_.Exception.Message)" -ForegroundColor Red
- return $null
- }
-}
-#region HTML Content
+#region HTML UI & CSS
function GetHtmlContent {
- @"
+@"
SVS TaskGate
+
+
+
+
-
+
On-Boarding
-
This new deployment method ensures everything is deployed smoothly!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
Tweaks
-
-
+
+
+
+
"@
}
-# Launch the UI
+#endregion
+
+
+# 3) LAUNCH THE UI
Start-Process "msedge.exe" -ArgumentList "--app=http://localhost:8081/"
-#region HTTP Listener Route Handling
+
+#region 4) ROUTE HANDLING
try {
- while ($listener.IsListening) {
- $ctx = $listener.GetContext()
- $req = $ctx.Request
- $res = $ctx.Response
- switch ($req.Url.AbsolutePath) {
- "/" {
- $html = GetHtmlContent
- $bytes = [System.Text.Encoding]::UTF8.GetBytes($html)
- $res.ContentType = "text/html"
- $res.ContentLength64 = $bytes.Length
- $res.OutputStream.Write($bytes,0,$bytes.Length)
- $res.OutputStream.Close()
- }
- "/getn8npw" {
- if ($req.HttpMethod -eq "POST") {
- $body = (New-Object IO.StreamReader $req.InputStream).ReadToEnd() | ConvertFrom-Json
- Get-N8nWebhookData -AuthHeaderValue $body.password
- $sites = Install-DattoRMM-Helper -ApiUrl $ApiUrl -ApiKey $ApiKey -ApiSecretKey $ApiSecretKey -FetchSitesOnly
- if ($sites) {
- $json = $sites | ConvertTo-Json
- $bytes = [System.Text.Encoding]::UTF8.GetBytes($json)
- $res.ContentType = "application/json"
- $res.ContentLength64 = $bytes.Length
- $res.OutputStream.Write($bytes,0,$bytes.Length)
- } else {
- $res.StatusCode = 500
- $res.OutputStream.Write(([System.Text.Encoding]::UTF8.GetBytes("No sites found")),0,14)
- }
- $res.OutputStream.Close()
- }
- }
- "/installSVSMSPModule" {
- if ($req.HttpMethod -eq "GET") {
- try { Install-SVSMSP -InstallToolkit; $msg="SVS Module triggered"; $code=200 }
- catch { $msg="Error: $_"; $code=500 }
- $res.StatusCode = $code
- $bytes = [System.Text.Encoding]::UTF8.GetBytes($msg)
- $res.OutputStream.Write($bytes,0,$bytes.Length)
- $res.OutputStream.Close()
- }
- }
- # … include the rest of your endpoints (/installrmm, /setSVSPowerplan, /installCyberQP, etc.) exactly as before …
- "/quit" {
- if ($req.HttpMethod -eq "GET") {
- $res.OutputStream.Write(([System.Text.Encoding]::UTF8.GetBytes("Shutting down")),0,12)
- $res.OutputStream.Close()
- $listener.Stop()
- break
- }
- }
- default {
- $res.StatusCode = 404
- $res.OutputStream.Write(([System.Text.Encoding]::UTF8.GetBytes("Not Found")),0,9)
- $res.OutputStream.Close()
- }
+ 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
- $listener.Stop()
- $listener.Close()
- }
+ if ($listener) {
+ Write-LogHybrid -Message "Stopping listener" -Level Info -TaskCategory Listener
+ $listener.Stop(); $listener.Close()
+ }
}