diff --git a/TGBeta.ps1 b/TGBeta.ps1
index 98a3b1e..1224ce7 100644
--- a/TGBeta.ps1
+++ b/TGBeta.ps1
@@ -1,46 +1,31 @@
### To Modify as of January 27 2025
-### let's start thinking about the write-log -TaskCategory "On-boarding" or "Off-boarding"
-### need RGB color codes form 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 it 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
-
+### Notes:
+### - This script creates a GUI with tabs (On-Boarding, Off-Boarding, Tweaks, Steph's Pick).
+### - In the On-Boarding tab, if the user selects “Select All,” then all checkboxes are checked.
+### In particular, the DattoRMM checkbox will be checked and its sub‑options will expand.
+### - All client‑side JavaScript is wrapped in a DOMContentLoaded event listener to ensure proper initialization.
# ---------------------------------------------------------------------------
-# 1) CREATE A GLOBAL LOG CACHE (NEW)
+# 1) CREATE A GLOBAL LOG CACHE
# ---------------------------------------------------------------------------
-# - Global log cache stores logs for session-wide accessibility.
-# - Logs are stored in a [System.Collections.ArrayList] for easy JSON conversion.
-# - Ensure log cache integrity during session restarts.
if (-not $Global:LogCache -or -not ($Global:LogCache -is [System.Collections.ArrayList])) {
$Global:LogCache = New-Object System.Collections.ArrayList
}
#region Write-LogHelper
-# ---------------------------------------------------------------------------
-# 2) DEFINE THE Write-LogHelper FUNCTION
-# ---------------------------------------------------------------------------
-# - Write-LogHelper manages logging with customizable levels, task categories, and optional event logging.
-# - Supported log levels: Info, Warning, Error, Success, General.
-# - Task categories should match high-level operations (e.g., "On-boarding", "Off-boarding").
if (-not (Get-Command -Name Write-Log -CommandType Function -ErrorAction SilentlyContinue)) {
- # If the Write-Log function doesn't exist, create the Write-LogHelper function
function Write-LogHelper {
param (
[string]$Message,
[ValidateSet("Info", "Warning", "Error", "Success", "General")]
[string]$Level = "Info",
- [string]$TaskCategory = "GeneralTask", # Task Category for the log entry
- [switch]$LogToEvent = $false, # Log to Windows Event Log
- [string]$EventSource = "SVSMSP_Module", # Event Source
- [string]$EventLog = "Application", # Event Log (default: Application)
- [int]$CustomEventID # Optional custom Event ID
+ [string]$TaskCategory = "GeneralTask",
+ [switch]$LogToEvent = $false,
+ [string]$EventSource = "SVSMSP_Module",
+ [string]$EventLog = "Application",
+ [int]$CustomEventID
)
-
- # Simplified Event ID mapping for consistent logging
$EventID = switch ($Level) {
"Info" { 1000 }
"Warning" { 2000 }
@@ -48,17 +33,13 @@ if (-not (Get-Command -Name Write-Log -CommandType Function -ErrorAction Silentl
"Success" { 4000 }
"General" { 1000 }
}
-
- # Icons for each level
$Icon = switch ($Level) {
- "Info" { [System.Char]::ConvertFromUtf32(0x1F4CB) } # Information icon
- "Warning" { ([char]0x26A0) } # Warning icon
- "Error" { ([char]0x274C) } # Error icon
- "Success" { ([char]0x2705) } # Success icon
- "General" { ([char]0x1F4E6) } # Package icon
+ "Info" { [System.Char]::ConvertFromUtf32(0x1F4CB) }
+ "Warning" { ([char]0x26A0) }
+ "Error" { ([char]0x274C) }
+ "Success" { ([char]0x2705) }
+ "General" { ([char]0x1F4E6) }
}
-
- # Map levels to colors for console output
$Color = switch ($Level) {
"Info" { "Cyan" }
"Warning" { "Yellow" }
@@ -66,26 +47,12 @@ if (-not (Get-Command -Name Write-Log -CommandType Function -ErrorAction Silentl
"Success" { "Green" }
"General" { "White" }
}
-
- # Write to the PowerShell console
- # Write-Host "$Icon [$Level] [$TaskCategory] $Message (Event ID: $EventID)" -ForegroundColor $Color
-
- # -------------------------------------------------------------------
- # 3) STORE LOGS IN GLOBAL CACHE
- # -------------------------------------------------------------------
- # - Cache format: Timestamp, Level, and Message for each log entry.
$logEntry = [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)
- # -------------------------------------------------------------------
- ### TODO: Add support for exporting logs to a persistent file.
- # Consider implementing a periodic export mechanism to save logs to a file.
- # Example: Export-LogCacheToFile -Path "C:\Logs\TaskLogs.json"
-
- # Optional: Log to Windows Event Log for system-wide visibility.
if ($LogToEvent) {
$EntryType = switch ($Level) {
"Info" { "Information" }
@@ -93,7 +60,6 @@ if (-not (Get-Command -Name Write-Log -CommandType Function -ErrorAction Silentl
"Error" { "Error" }
default { "Information" }
}
-
try {
if (-not (Get-EventLog -LogName $EventLog -Source $EventSource -ErrorAction SilentlyContinue)) {
New-EventLog -LogName $EventLog -Source $EventSource -ErrorAction SilentlyContinue
@@ -106,9 +72,6 @@ if (-not (Get-Command -Name Write-Log -CommandType Function -ErrorAction Silentl
}
}
}
-
- ### Hybrid Function:
- # Wrapper for Write-LogHelper to simplify usage across modules.
function Write-LogHybrid {
param (
[string]$Message,
@@ -126,7 +89,6 @@ if (-not (Get-Command -Name Write-Log -CommandType Function -ErrorAction Silentl
}
}
else {
- # If Write-Log exists, define Write-LogHybrid to use Write-Log
function Write-LogHybrid {
param (
[string]$Message,
@@ -143,34 +105,24 @@ else {
-CustomEventID $CustomEventID
}
}
-
-# Example usage of Write-LogHybrid
Write-LogHybrid -Message "Starting SVS TaskGate" -Level "Info" -TaskCategory "SVSTaskGate" -LogToEvent:$true
#endregion
#region Install-DattoRMM-Helper
-
function Install-DattoRMM-Helper {
param (
[string]$ApiUrl,
[string]$ApiKey,
[string]$ApiSecretKey,
- [switch]$FetchSitesOnly, # Fetch client sites without performing installation
- [string]$SiteName, # For actual installation, pass the selected site Name
- [string]$SiteUID # For actual installation, pass the selected site UID
+ [switch]$FetchSitesOnly,
+ [string]$SiteName,
+ [string]$SiteUID
)
-
-
- # Ensure mandatory parameters are provided
if (-not $ApiUrl -or -not $ApiKey -or -not $ApiSecretKey) {
Write-Log -Message "Missing required parameters. Please provide ApiUrl, ApiKey, and ApiSecretKey." -Level "Error" -LogToEvent
return
}
-
- # Enable secure protocols
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
-
- # Step 1: Fetch OAuth token
Write-Log -Message "Fetching OAuth token..." -Level "Info"
try {
$securePassword = ConvertTo-SecureString -String 'public' -AsPlainText -Force
@@ -186,15 +138,10 @@ function Install-DattoRMM-Helper {
Write-Log -Message "Failed to fetch OAuth token. Details: $($_.Exception.Message)" -Level "Error" -LogToEvent
return
}
-
- # Set headers for the API request
- $getHeaders = @{"Authorization" = "Bearer $requestToken"}
-
- # Step 2: Fetch list of sites
+ $getHeaders = @{ "Authorization" = "Bearer $requestToken" }
if ($FetchSitesOnly) {
Write-Host "Fetching list of sites from the Datto RMM API..." -ForegroundColor Cyan
try {
- $getHeaders = @{"Authorization" = "Bearer $requestToken" }
$getSites = Invoke-WebRequest -Uri "$ApiUrl/api/v2/account/sites" -Method Get -Headers $getHeaders -ContentType "application/json"
$sitesJson = $getSites.Content | ConvertFrom-Json
$siteList = $sitesJson.sites | ForEach-Object {
@@ -214,52 +161,27 @@ function Install-DattoRMM-Helper {
}
#endregion
-
-
#region SVS Module
-
-### SVS Module Overview:
-# - This section includes the Install-SVSMSP function, which handles:
-# 1. Cleanup of old modules and repositories.
-# 2. Installation of new modules and repositories.
-# 3. Setting execution policies and prerequisites.
-# - TODO:
-# 1. Validate all parameters for completeness and add error messages for missing inputs.
-# 2. Refactor cleanup and installation steps for modularity and reusability.
-
-
function Install-SVSMSP {
param (
- # Cleanup flag: Removes old modules and repositories if enabled.
[switch]$Cleanup,
-
- # Toolkit installation flag: Installs required modules and repositories.
[switch]$InstallToolkit,
-
- # Module settings
[Parameter(Mandatory = $false)]
[array]$AllModules = @(
@{ ModuleName = "SVS_Toolkit" },
@{ ModuleName = "SVSMSP" }
),
-
[Parameter(Mandatory = $false)]
[string]$NewModuleName = "SVSMSP",
-
- # Repository settings
[Parameter(Mandatory = $false)]
[array]$AllRepositories = @(
@{ RepoName = "SVS_Repo" },
@{ RepoName = "SVS_Toolkit" }
),
-
[Parameter(Mandatory = $false)]
[string]$NewRepositoryName = "SVS_Repo",
-
[Parameter(Mandatory = $false)]
[string]$NewRepositoryURL = "http://proget.svstools.ca:8083/nuget/SVS_Repo/",
-
- # Commands to check
[Parameter(Mandatory = $false)]
[array]$CommandsToCheck = @(
"Install-DattoRMM",
@@ -268,22 +190,12 @@ function Install-SVSMSP {
"Install-Splashtop",
"Install-ThreatLocker",
"Install-SVSHelpdesk"
-
),
-
- # Log file path for tracking installation steps
[Parameter(Mandatory = $false)]
[string]$LogFilePath = "$env:SVSMSP\svstoolkit.log"
-
)
-
- ### Function: Perform-Cleanup
- # - Removes all old modules and repositories.
- # - Logs each step for debugging purposes.
function Perform-Cleanup {
- Write-LogHybrid -Message "Cleanup mode enabled. Starting cleanup process..." -Level "Info" -LogToEvent
-
- # Step 1: Remove all old modules
+ Write-LogHybrid -Message "Cleanup mode enabled. Starting cleanup process..." -Level "Info" -LogToEvent
Write-LogHybrid -Message "Starting cleanup of old modules..." -Level "Info" -LogToEvent
foreach ($module in $AllModules) {
$ModuleName = $module.ModuleName
@@ -303,8 +215,6 @@ function Install-SVSMSP {
Write-LogHybrid -Message "Module '$ModuleName' not found. Skipping..." -Level "Info" -LogToEvent
}
}
-
- # Step 2: Remove all old repositories
Write-LogHybrid -Message "Starting cleanup of old repositories..." -Level "Info" -LogToEvent
foreach ($repo in $AllRepositories) {
$RepoName = $repo.RepoName
@@ -322,36 +232,23 @@ function Install-SVSMSP {
Write-LogHybrid -Message "Repository '$RepoName' does not exist. Skipping removal." -Level "Info" -LogToEvent
}
}
-
- Write-LogHybrid -Message "Cleanup process completed successfully." -Level "Success" -LogToEvent
+ Write-LogHybrid -Message "Cleanup process completed successfully." -Level "Success" -LogToEvent
}
-
- ### Function: Perform-ToolkitInstallation
- # - Handles the installation of new repositories and modules.
- # - Ensures execution policies are correctly set.
function Perform-ToolkitInstallation {
-
- # Step 1: Cleanup old modules and repositories
Perform-Cleanup
-
- # Step 2: Set Execution Policy
$localMachineExecutionPolicy = Get-ExecutionPolicy -Scope LocalMachine
if ($localMachineExecutionPolicy -ne "RemoteSigned") {
- Write-LogHybrid -Message "Setting execution policy to RemoteSigned..." -Level "Warning" -LogToEvent
+ Write-LogHybrid -Message "Setting execution policy to RemoteSigned..." -Level "Warning" -LogToEvent
try {
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine -Force
- Write-LogHybrid -Message "Execution policy set to RemoteSigned successfully." -Level "Success" -LogToEvent
+ Write-LogHybrid -Message "Execution policy set to RemoteSigned successfully." -Level "Success" -LogToEvent
}
catch {
- Write-LogHybrid -Message "Failed to set execution policy. Error: $_" -Level "Error" -LogToEvent
+ Write-LogHybrid -Message "Failed to set execution policy. Error: $_" -Level "Error" -LogToEvent
return
}
}
-
- # Step 3: Ensure NuGet is Installed
Install-PackageProvider -Name "NuGet" -Force -Scope AllUsers -Confirm:$false
-
- # Step 4: Register the new repository
Write-LogHybrid -Message "Registering the new repository '$NewRepositoryName'..." -Level "Info" -LogToEvent
try {
if (!(Get-PSRepository -Name $NewRepositoryName -ErrorAction SilentlyContinue)) {
@@ -362,8 +259,6 @@ function Install-SVSMSP {
catch {
Write-LogHybrid -Message "Failed to register new repository '$NewRepositoryName'. Error: $($_.Exception.Message)" -Level "Error" -LogToEvent
}
-
- # Step 5: Install the new module
Write-LogHybrid -Message "Installing the new module '$NewModuleName'..." -Level "Info" -LogToEvent
try {
Install-Module -Name $NewModuleName -Repository $NewRepositoryName -Scope AllUsers -Force
@@ -372,82 +267,70 @@ function Install-SVSMSP {
catch {
Write-LogHybrid -Message "Failed to install new module '$NewModuleName'. Error: $($_.Exception.Message)" -Level "Error" -LogToEvent
}
-
- Write-LogHybrid -Message "Toolkit installation process completed successfully." -Level "Success" -LogToEvent
+ Write-LogHybrid -Message "Toolkit installation process completed successfully." -Level "Success" -LogToEvent
}
-
- ### Function Execution Logic
- # - Determines whether to run cleanup, toolkit installation, or default to toolkit installation mode.
- Write-LogHybrid -Message "Install-SVSMSP function started." -Level "Info" -LogToEvent
-
+ Write-LogHybrid -Message "Install-SVSMSP function started." -Level "Info" -LogToEvent
if ($Cleanup) {
Perform-Cleanup
return
}
-
if ($InstallToolkit) {
Perform-ToolkitInstallation
return
}
-
Write-LogHybrid -Message "No specific mode specified. Defaulting to toolkit installation mode..." -Level "Info" -LogToEvent
Perform-ToolkitInstallation
}
-#endregion SVS Module
+#endregion
+
+#region NEW: Install-StephsPick
+function Install-StephsPick {
+ param (
+ [array]$Packages
+ )
+ Write-LogHybrid -Message "Starting Steph's Pick installation" -Level "Info"
+ foreach ($package in $Packages) {
+ try {
+ $cmd = "winget install --id $package --silent"
+ Write-LogHybrid -Message "Executing: $cmd" -Level "Info"
+ Invoke-Expression $cmd
+ }
+ catch {
+ Write-LogHybrid -Message "Error installing package $package`: $($_.Exception.Message)" -Level "Error"
+ }
+ }
+ Write-LogHybrid -Message "Steph's Pick installation completed" -Level "Success"
+}
+#endregion
# ----------------------------------------------------------------------------------
# START THE HTTP LISTENER
# ----------------------------------------------------------------------------------
-# This listener serves as the backend for handling requests from the GUI.
-# It supports multiple routes, such as:
-# - "/" (Root): Serves the HTML GUI.
-# - "/getn8npw": Fetches n8n password and site information.
-# - "/installSVSMSPModule": Triggers the installation of SVSMSP modules.
-# - "/installrmm": Handles RMM installation with dynamic parameters.
-# - Additional routes for tweaks and other tasks.
-
-### Listener Initialization with Error Handling
try {
- # Create a new HttpListener object
$listener = New-Object System.Net.HttpListener
-
- # Check if the object was successfully created
if (-not $listener) {
throw "Failed to initialize HttpListener."
}
-
- # Add prefix for the listener
$listener.Prefixes.Add("http://localhost:8081/")
Write-LogHybrid -Message "Listener initialized with prefix http://localhost:8081/" -Level "Info"
-
- # Start the listener
$listener.Start()
Write-LogHybrid -Message "Listener started successfully." -Level "Info"
} catch {
- # Log the error and rethrow it for visibility
Write-LogHybrid -Message "Critical error initializing listener: $($_.Exception.Message)" -Level "Error"
throw $_
}
-
-
function Get-N8nWebhookData {
param (
[Parameter(Mandatory = $true)]
[string]$AuthHeaderValue
)
-
$url = "https://automate.svstools.ca/webhook/svsmspkit"
- $headers = @{
- "SVSMSPKit" = $AuthHeaderValue
- }
+ $headers = @{ "SVSMSPKit" = $AuthHeaderValue }
try {
$response = Invoke-RestMethod -Uri $url -Headers $headers -Method Get
Write-Host "Response received successfully:" -ForegroundColor Green
-
$data = $response
-
- # Map fields
$global:Comment_SVSmodule = $data._Comment_SVSmodule
$global:ModuleName = $data.ModuleName
$global:RepositoryURL = $data.RepositoryURL
@@ -459,10 +342,6 @@ function Get-N8nWebhookData {
$global:ApiUrl = $data.ApiUrl
$global:ApiKey = $data.ApiKey
$global:ApiSecretKey = $data.ApiSecretKey
-
-
-
- # return $data
}
catch {
Write-Host "Error making the GET request:" -ForegroundColor Red
@@ -471,984 +350,751 @@ function Get-N8nWebhookData {
}
}
-
-# Define the HTML Content with an Off-Boarding Tab
function GetHtmlContent {
- @"
+@"
-
-
- SVS TaskGate
-
-
+
-
-

+
+

+
+