Files
Logo/TGBeta.ps1
2025-01-31 17:25:15 -05:00

1579 lines
69 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
### To Modify as of January 27 2025
### 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.
### - All client-side JavaScript is wrapped in a DOMContentLoaded event listener to ensure proper initialization.
# ---------------------------------------------------------------------------
# 1) CREATE A 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)) {
function Write-LogHelper {
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
)
$EventID = switch ($Level) {
"Info" { 1000 }
"Warning" { 2000 }
"Error" { 3000 }
"Success" { 4000 }
"General" { 1000 }
}
$Icon = switch ($Level) {
"Info" { [System.Char]::ConvertFromUtf32(0x1F4CB) }
"Warning" { ([char]0x26A0) }
"Error" { ([char]0x274C) }
"Success" { ([char]0x2705) }
"General" { ([char]0x1F4E6) }
}
$Color = switch ($Level) {
"Info" { "Cyan" }
"Warning" { "Yellow" }
"Error" { "Red" }
"Success" { "Green" }
"General" { "White" }
}
$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)
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 "([char]0x26A0) [Warning] [EventLog] Failed to write to Event Log: $($_.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
}
}
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
#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-Log -Message "Missing required parameters. Please provide ApiUrl, ApiKey, and ApiSecretKey." -Level "Error" -LogToEvent
return
}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Write-Log -Message "Fetching OAuth token..." -Level "Info"
try {
$securePassword = ConvertTo-SecureString -String 'public' -AsPlainText -Force
$apiGenToken = Invoke-WebRequest -Credential (New-Object -TypeName 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-Log -Message "OAuth token fetched successfully." -Level "Success" -LogToEvent
} catch {
Write-Log -Message "Failed to fetch OAuth token. Details: $($_.Exception.Message)" -Level "Error" -LogToEvent
return
}
$getHeaders = @{ "Authorization" = "Bearer $requestToken" }
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 $getHeaders -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 from the API. Details: $($_.Exception.Message)" -ForegroundColor Red
return
}
}
}
#endregion
#region SVS Module
function Install-SVSMSP {
param (
[switch]$Cleanup,
[switch]$InstallToolkit,
[Parameter(Mandatory = $false)]
[array]$AllModules = @(
@{ ModuleName = "SVS_Toolkit" },
@{ ModuleName = "SVSMSP" }
),
[Parameter(Mandatory = $false)]
[string]$NewModuleName = "SVSMSP",
[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/",
[Parameter(Mandatory = $false)]
[array]$CommandsToCheck = @(
"Install-DattoRMM",
"Install-CyberQP",
"Install-RocketCyber",
"Install-Splashtop",
"Install-ThreatLocker",
"Install-SVSHelpdesk"
),
[Parameter(Mandatory = $false)]
[string]$LogFilePath = "$env:SVSMSP\svstoolkit.log"
)
function Perform-Cleanup {
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
if (Get-Module -Name $ModuleName -ListAvailable) {
Write-LogHybrid -Message "Removing module '$ModuleName'..." -Level "Warning" -LogToEvent
try {
Get-Module -Name $ModuleName -ListAvailable | ForEach-Object {
Uninstall-Module -Name $_.Name -AllVersions -Force
}
Write-LogHybrid -Message "Module '$ModuleName' removed successfully." -Level "Success" -LogToEvent
}
catch {
Write-LogHybrid -Message "Failed to remove module '$ModuleName'. Error: $($_.Exception.Message)" -Level "Error" -LogToEvent
}
}
else {
Write-LogHybrid -Message "Module '$ModuleName' not found. Skipping..." -Level "Info" -LogToEvent
}
}
Write-LogHybrid -Message "Starting cleanup of old repositories..." -Level "Info" -LogToEvent
foreach ($repo in $AllRepositories) {
$RepoName = $repo.RepoName
Write-LogHybrid -Message "Removing repository '$RepoName'..." -Level "Warning" -LogToEvent
if (Get-PSRepository -Name $RepoName -ErrorAction SilentlyContinue) {
try {
Unregister-PSRepository -Name $RepoName -ErrorAction Stop
Write-LogHybrid -Message "Repository '$RepoName' removed successfully." -Level "Success" -LogToEvent
}
catch {
Write-LogHybrid -Message "Failed to remove repository '$RepoName'. Error: $($_.Exception.Message)" -Level "Error" -LogToEvent
}
}
else {
Write-LogHybrid -Message "Repository '$RepoName' does not exist. Skipping removal." -Level "Info" -LogToEvent
}
}
Write-LogHybrid -Message "Cleanup process completed successfully." -Level "Success" -LogToEvent
}
function Perform-ToolkitInstallation {
Perform-Cleanup
$localMachineExecutionPolicy = Get-ExecutionPolicy -Scope LocalMachine
if ($localMachineExecutionPolicy -ne "RemoteSigned") {
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
}
catch {
Write-LogHybrid -Message "Failed to set execution policy. Error: $_" -Level "Error" -LogToEvent
return
}
}
Install-PackageProvider -Name "NuGet" -Force -Scope AllUsers -Confirm:$false
Write-LogHybrid -Message "Registering the new repository '$NewRepositoryName'..." -Level "Info" -LogToEvent
try {
if (!(Get-PSRepository -Name $NewRepositoryName -ErrorAction SilentlyContinue)) {
Register-PSRepository -Name $NewRepositoryName -SourceLocation $NewRepositoryURL -InstallationPolicy Trusted
Write-LogHybrid -Message "Repository '$NewRepositoryName' registered successfully." -Level "Success" -LogToEvent
}
}
catch {
Write-LogHybrid -Message "Failed to register new repository '$NewRepositoryName'. Error: $($_.Exception.Message)" -Level "Error" -LogToEvent
}
Write-LogHybrid -Message "Installing the new module '$NewModuleName'..." -Level "Info" -LogToEvent
try {
Install-Module -Name $NewModuleName -Repository $NewRepositoryName -Scope AllUsers -Force
Write-LogHybrid -Message "Module '$NewModuleName' installed successfully." -Level "Success" -LogToEvent
}
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 "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
#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
# ----------------------------------------------------------------------------------
try {
$listener = New-Object System.Net.HttpListener
if (-not $listener) {
throw "Failed to initialize HttpListener."
}
$listener.Prefixes.Add("http://localhost:8081/")
Write-LogHybrid -Message "Listener initialized with prefix http://localhost:8081/" -Level "Info"
$listener.Start()
Write-LogHybrid -Message "Listener started successfully." -Level "Info"
} catch {
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 }
try {
$response = Invoke-RestMethod -Uri $url -Headers $headers -Method Get
Write-Host "Response received successfully:" -ForegroundColor Green
$data = $response
$global:Comment_SVSmodule = $data._Comment_SVSmodule
$global:ModuleName = $data.ModuleName
$global:RepositoryURL = $data.RepositoryURL
$global:OldRepo = $data.OldRepo
$global:NewRepo = $data.NewRepo
$global:CommandsToCheck = $data.CommandsToCheck
$global:LogFilePath = $data.LogFilePath
$global:Comment_DRMM = $data._Comment_DRMM
$global:ApiUrl = $data.ApiUrl
$global:ApiKey = $data.ApiKey
$global:ApiSecretKey = $data.ApiSecretKey
}
catch {
Write-Host "Error making the GET request:" -ForegroundColor Red
Write-Host $_.Exception.Message
return $null
}
}
function GetHtmlContent {
@"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SVS TaskGate</title>
<link rel="icon" href="https://git.svstools.com/syelle/Logo/raw/branch/main/SVS_Favicon.ico" type="image/x-icon">
<style>
:root {
--background-color: rgba(18, 18, 18, 1);
--border-color: rgba(255, 127, 0, 0.25);
--white-color: rgba(255, 255, 255);
--gray-color: rgba(102, 102, 102);
--dark-gray-color: rgba(51, 51, 51);
--light-gray-color: rgba(187, 187, 187);
--btn-sidebar-light-gray: rgba(68, 68, 68);
--btn-sidebar-blue: rgba(30, 144, 255, 1);
--btn-hover: rgba(0, 86, 179, 1);
--btn-hover-scale: 1.05;
--btn-success: rgba(40, 167, 69);
--btn-success-disabled: rgba(108, 117, 125);
--btn-danger: rgba(220, 53, 69);
}
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: var(--background-color);
color: var(--white-color);
height: 100%;
overflow: hidden;
}
.logo-container {
text-align: left;
padding: 20px;
background-color: var(--background-color);
}
.logo-container img {
max-width: 300px;
height: auto;
}
.subtitle {
font-size: 1.2rem;
color: var(--gray-color);
margin-top: 0.5em;
}
.container {
display: flex;
height: 100vh;
overflow: hidden;
}
.sidebar {
width: 200px;
height: 100%;
background-color: var(--background-color);
padding: 10px;
}
.sidebar button {
display: block;
width: 100%;
margin-bottom: 10px;
padding: 10px;
color: var(--white-color);
background-color: var(--btn-sidebar-light-gray);
border: none;
border-radius: 5px;
cursor: pointer;
text-align: left;
transition: background-color 0.3s ease, transform 0.2s ease;
}
.sidebar button.active {
background-color: var(--btn-sidebar-blue);
}
.sidebar button:hover {
background-color: var(--btn-hover);
transform: scale(var(--btn-hover-scale));
}
.content {
flex: 1;
padding: 20px;
overflow-y: auto;
max-height: calc(100vh - 50px);
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
}
.checkbox-group label {
margin: 0;
padding: 0;
line-height: 1.5;
display: flex;
align-items: center;
}
.password-input,
.dropdown {
width: 30%;
padding: 10px;
margin-bottom: 20px;
border-radius: 5px;
border: 1px solid var(--border-color);
background-color: var(--background-color);
color: var(--white-color);
}
#n8nPasswordContainer {
display: none;
margin-top: 20px;
}
.button-group {
margin-top: 20px;
text-align: right;
}
.button-group button {
padding: 10px 20px;
margin-left: 10px;
border: none;
border-radius: 5px;
cursor: pointer;
}
.install-button {
background-color: var(--btn-success);
color: var(--white-color);
}
.install-button:disabled {
background-color: var(--btn-success-disabled);
cursor: not-allowed;
}
.exit-button {
background-color: var(--btn-danger);
color: var(--white-color);
}
.columns-container {
display: flex;
justify-content: center;
gap: 20px;
align-items: flex-start;
padding: 0;
}
.column {
width: 48%;
border: 2px solid var(--border-color);
border-radius: 8px;
padding: 10px;
background-color: var(--background-color);
box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.3);
margin: 0;
}
.log {
width: 80%;
margin-top: 20px;
padding: 10px;
background-color: var(--dark-gray-color);
color: var(--light-gray-color);
border-radius: 5px;
max-height: 500px;
overflow-y: auto;
}
@media (max-width: 768px) {
.container {
flex-direction: column;
}
.sidebar {
width: 100%;
}
}
</style>
</head>
<body>
<div class="logo-container">
<img src="https://git.svstools.com/syelle/Logo/raw/branch/main/SVS_logo.svg" alt="SVS Logo">
</div>
<div class="container">
<div class="sidebar">
<button class="tab-button active" data-tab="onboardTab" aria-expanded="true">On-Boarding</button>
<button class="tab-button" data-tab="offboardTab" aria-expanded="false">Off-Boarding</button>
<button class="tab-button" data-tab="tweaksTab" aria-expanded="false">Tweaks</button>
<button class="tab-button" data-tab="stephsPickTab" aria-expanded="false">Steph's Pick</button>
</div>
<div class="content">
<!-- On-Boarding Tab -->
<div id="onboardTab" class="tab-content active">
<h2>On-Boarding</h2>
<h3 class="subtitle">This new deployment method ensures everything is successfully deployed with greater ease!</h3>
<div class="columns-container">
<div class="checkbox-group column" id="leftColumn">
<h3 style="font-size: 1.5rem; font-weight: bold;">SVSMSP Stack</h3>
<label>
<input type="checkbox" id="selectAllLeftCheckbox" onclick="toggleLeftColumnCheckboxes(this)">
Select All
</label>
<label>
<input type="checkbox" class="left-checkbox" name="setSVSPowerplan" id="SetSVSPowerplanCheckbox">
Set SVS Powerplan
</label>
<label>
<input type="checkbox" class="left-checkbox" name="installSVSMSPModule" id="installSVSMSPModuleCheckbox">
Install SVSMSP Module
</label>
<label>
<input type="checkbox" class="left-checkbox" name="installCyberQP" id="installCyberQPCheckbox">
Install CyberQP
</label>
<label>
<input type="checkbox" class="left-checkbox" name="installSplashtop" id="installSplashtopCheckbox">
Install Splashtop
</label>
<label>
<input type="checkbox" class="left-checkbox" name="installSVSHelpDesk" id="installSVSHelpDeskCheckbox">
Install SVSHelpDesk
</label>
<label>
<input type="checkbox" class="left-checkbox" name="installThreatLocker" id="installThreatLockerCheckbox">
Install ThreatLocker
</label>
<label>
<input type="checkbox" class="left-checkbox" name="installRocketCyber" id="installRocketCyberCheckbox">
Install RocketCyber
</label>
<label>
<input type="checkbox" class="left-checkbox" name="installDattoRMM" id="installDattoRMMCheckbox" onclick="toggleDattoRMMOptions()">
Install DattoRMM
</label>
<div id="dattoRMMOptionsContainer" style="display:none; padding-left: 20px;">
<label>
<input type="checkbox" class="left-checkbox" name="dattoRMMOption" value="inputVar">
Copy Site Variables
</label>
<label>
<input type="checkbox" class="left-checkbox" name="dattoRMMOption" value="rmm">
Install DRMM Agent
</label>
<label>
<input type="checkbox" class="left-checkbox" name="dattoRMMOption" value="exe">
Download.exe
</label>
<br><br>
</div>
</div>
<div class="checkbox-group column" id="rightColumn">
<h3 style="font-size: 1.5rem; font-weight: bold;">Optional</h3>
<label>
<input type="checkbox" class="right-checkbox" name="EnableBitLocker" id="EnableBitLockerCheckbox">
Enable Bitlocker
</label>
<label>
<input type="checkbox" class="right-checkbox" name="setedgedefaultsearch" id="setedgedefaultsearchCheckbox">
Set Edge Default Search Engine
</label>
</div>
</div>
<div id="n8nPasswordContainer" style="display: none;">
<label for="n8nPassword">Enter Password:</label><br>
<input type="password" id="n8nPassword" class="password-input" placeholder="Enter Password">
</div>
<br>
<div id="DattoRMMContainer" style="display: none;">
<label for="dattoRmmDropdown">Select a Datto RMM site:</label><br>
<select id="dattoRmmDropdown" class="dropdown">
<option value="">Fetching sites...</option>
$siteOptions
</select>
</div>
<div class="button-group">
<button class="install-button" id="fetchSitesButton" onclick="fetchSites()" disabled>Fetch Sites</button>
<!-- When "Install" is clicked, triggerInstall() will first install the module if needed -->
<button class="install-button" onclick="triggerInstall()">Install</button>
</div>
</div>
<!-- Off-Boarding Tab -->
<div id="offboardTab" class="tab-content inactive">
<h2>Off-Boarding</h2>
<div class="checkbox-group">
<label>
<input type="checkbox" id="selectAllOffboardCheckbox" onclick="toggleOffboardCheckboxes(this)">
Select All
</label>
<label>
<input type="checkbox" name="uninstallSVSMSPModule" id="uninstallSVSMSPModuleCheckbox">
Uninstall SVSMSP Module
</label>
<label>
<input type="checkbox" name="uninstallThreatLocker" id="uninstallThreatLockerCheckbox">
Uninstall ThreatLocker
</label>
<label>
<input type="checkbox" name="uninstallCyberQP" id="uninstallCyberQPCheckbox">
Uninstall CyberQP
</label>
<label>
<input type="checkbox" name="uninstallDattoEDR" id="uninstallDattoEDRCheckbox">
Uninstall DattoEDR
</label>
<label>
<input type="checkbox" name="uninstallDattoRMM" id="uninstallDattoRMMCheckbox">
Uninstall DattoRMM
</label>
<label>
<input type="checkbox" name="uninstallDattoDEB" id="uninstallDattoDEBCheckbox">
Uninstall DattoDEB
</label>
<label>
<input type="checkbox" name="uninstallRocketCyber" id="uninstallRocketCyberCheckbox">
Uninstall RocketCyber
</label>
<label>
<input type="checkbox" name="uninstallSplashtop" id="uninstallSplashtopCheckbox">
Uninstall splashtop
</label>
<label>
<input type="checkbox" name="uninstallSVSHelpdesk" id="uninstallSVSHelpdeskCheckbox">
Uninstall SVSHelpdesk
</label>
<label>
<input type="checkbox" name="uninstallSVSWatchtower" id="uninstallSVSWatchtowerCheckbox">
Uninstall SVSWatchtower
</label>
<div class="button-group">
<button class="install-button" onclick="triggerOffboard()">Offboard</button>
</div>
</div>
</div>
<!-- Tweaks Tab -->
<div id="tweaksTab" class="tab-content inactive">
<h2>Tweaks</h2>
<div class="columns-container">
<div class="column" id="tweaksColumn1">
<h3>System Optimizations</h3>
<div class="checkbox-group">
<label>
<input type="checkbox" name="setedgedefaultsearch" id="setedgedefaultsearchCheckbox">
Set Edge Default Search Engine
</label>
<label>
<input type="checkbox" name="setWindowsPerformance" id="setWindowsPerformanceCheckbox" onclick="toggleRadioButtons(this)">
Optimize Windows Performance
</label>
<div class="radio-group" id="windowsPerformanceOptions" style="margin-left: 20px; display: none;">
<label>
<input type="radio" name="optimizeWindowsPerformanceLevel" value="full">
Full
</label>
<label>
<input type="radio" name="optimizeWindowsPerformanceLevel" value="partial">
Partial
</label>
<label>
<input type="radio" name="optimizeWindowsPerformanceLevel" value="none" checked>
None
</label>
</div>
<label>
<input type="checkbox" name="stopUnnecessaryServices" id="stopUnnecessaryServicesCheckbox">
Stop Unnecessary Services
</label>
</div>
</div>
<div class="column" id="tweaksColumn2">
<h3>Additional Tweaks</h3>
<div class="checkbox-group">
<label>
<input type="checkbox" name="disableAnimations" id="disableAnimationsCheckbox">
Disable Animations
</label>
<label>
<input type="checkbox" name="optimizePerformance" id="optimizePerformanceCheckbox">
Optimize Application Performance
</label>
<label>
<input type="checkbox" name="increaseFontSize" id="increaseFontSizeCheckbox">
Increase Font Size
</label>
</div>
</div>
<div class="column" id="tweaksColumn3">
<h3>Miscellaneous</h3>
<div class="checkbox-group">
<label>
<input type="checkbox" name="enableDarkMode" id="enableDarkModeCheckbox">
Enable Dark Mode
</label>
<label>
<input type="checkbox" name="clearTempFiles" id="clearTempFilesCheckbox">
Clear Temporary Files
</label>
</div>
</div>
</div>
<div class="button-group">
<button class="install-button" onclick="triggerTweaks()">Apply Tweaks</button>
</div>
</div>
<!-- Steph's Pick Tab -->
<div id="stephsPickTab" class="tab-content inactive">
<h2>Steph's Pick</h2>
<div class="column">
<h3 style="font-size: 1.5rem; font-weight: bold;">Apps</h3>
<div class="checkbox-group">
<label>
<input type="checkbox" id="installAppleiCloudCheckbox" name="installAppleiCloud">
Install Apple iCloud
</label>
<label>
<input type="checkbox" id="installObsidianCheckbox" name="installObsidian">
Install Obsidian
</label>
<label>
<input type="checkbox" id="installFlameshotCheckbox" name="installFlameshot">
Install Flameshot
</label>
<label>
<input type="checkbox" id="installSublimeTextCheckbox" name="installSublimeText">
Install Sublime Text 4
</label>
</div>
</div>
<div class="button-group">
<button class="install-button" onclick="triggerStephsPick()">Install Steph's Pick</button>
</div>
</div>
<!-- Shared Exit Button -->
<div class="button-group">
<button class="exit-button" onclick="endSession()">Exit</button>
</div>
<!-- Log Area -->
<div class="log" id="logArea">
<p>Logs will appear here...</p>
</div>
</div>
</div>
<script>
// Wrap all JavaScript in DOMContentLoaded to ensure proper initialization.
document.addEventListener('DOMContentLoaded', function() {
// Tab Switching
const tabButtons = document.querySelectorAll('.tab-button');
const tabContents = document.querySelectorAll('.tab-content');
tabButtons.forEach(button => {
button.addEventListener('click', () => {
tabButtons.forEach(btn => {
btn.classList.remove('active');
btn.setAttribute('aria-expanded', 'false');
});
tabContents.forEach(tab => tab.classList.remove('active'));
button.classList.add('active');
button.setAttribute('aria-expanded', 'true');
document.getElementById(button.dataset.tab).classList.add('active');
});
});
// Updated Select All functionality for the left column:
// This now calls toggleDattoRMMOptions() to ensure Datto subitems expand.
window.toggleLeftColumnCheckboxes = function(selectAllCheckbox) {
const leftCheckboxes = document.querySelectorAll('#leftColumn input[type="checkbox"]:not(#selectAllLeftCheckbox)');
leftCheckboxes.forEach(checkbox => {
checkbox.checked = selectAllCheckbox.checked;
});
// Instead of toggleDattoRMMVisibility, call toggleDattoRMMOptions to handle sub-items.
toggleDattoRMMOptions();
};
// Offboard Select All
window.toggleOffboardCheckboxes = function(selectAllCheckbox) {
const checkboxes = document.querySelectorAll('#offboardTab input[type="checkbox"]:not(#selectAllOffboardCheckbox)');
checkboxes.forEach(checkbox => {
checkbox.checked = selectAllCheckbox.checked;
});
};
// DattoRMM options toggling
window.toggleDattoRMMOptions = function() {
const dattoRMMCheckbox = document.getElementById('installDattoRMMCheckbox');
const optionsContainer = document.getElementById('dattoRMMOptionsContainer');
const n8nPasswordContainer = document.getElementById('n8nPasswordContainer');
const dattoRMMContainer = document.getElementById('DattoRMMContainer');
const subCheckboxes = document.querySelectorAll('#dattoRMMOptionsContainer input[type="checkbox"]');
if (dattoRMMCheckbox.checked) {
optionsContainer.style.display = 'block';
n8nPasswordContainer.style.display = 'block';
dattoRMMContainer.style.display = 'block';
subCheckboxes.forEach(subCheckbox => {
subCheckbox.checked = true;
});
} else {
optionsContainer.style.display = 'none';
n8nPasswordContainer.style.display = 'none';
dattoRMMContainer.style.display = 'none';
subCheckboxes.forEach(subCheckbox => {
subCheckbox.checked = false;
});
}
};
// Trigger Offboard
window.triggerOffboard = function() {
const checkboxes = document.querySelectorAll('#offboardTab input[type="checkbox"]:not(#selectAllOffboardCheckbox)');
const selectedTasks = Array.from(checkboxes)
.filter(checkbox => checkbox.checked)
.map(checkbox => checkbox.name);
if (selectedTasks.length === 0) {
appendLog("Please select at least one offboarding task.", "red");
return;
}
appendLog("Starting offboarding tasks...", "yellow");
fetch('/offboard', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ SelectedTasks: selectedTasks })
})
.then(response => {
if (!response.ok) {
throw new Error('Failed to execute offboarding tasks.');
}
return response.text();
})
.then(message => {
appendLog(message, "green");
})
.catch(error => {
appendLog("Error: " + error.message, "red");
});
};
// Toggle radio buttons for Windows Performance
window.toggleRadioButtons = function(checkbox) {
const radioGroup = document.getElementById("windowsPerformanceOptions");
if (checkbox.checked) {
radioGroup.style.display = "block";
} else {
radioGroup.style.display = "none";
const radios = radioGroup.querySelectorAll('input[type="radio"]');
radios.forEach(radio => {
radio.checked = false;
});
radios[2].checked = true;
}
};
// triggerInstall() function for On-Boarding tab
window.triggerInstall = async function() {
// If the "Install SVSMSP Module" checkbox is checked, install that module first.
if (document.querySelector('input[name="installSVSMSPModule"]').checked) {
appendLog("Installing SVSMSP Module (Priority 1)...", "cyan");
try {
let response = await fetch('/installSVSMSPModule', { method: 'GET' });
if (!response.ok) {
throw new Error("Failed to install SVSMSP Module.");
}
appendLog("SVSMSP Module installation completed.", "green");
} catch (error) {
appendLog("Error installing SVSMSP Module: " + error.message, "red");
return; // Abort further installation if module installation fails.
}
}
// Continue with other tasks.
if (document.querySelector('input[name="installDattoRMM"]').checked) {
appendLog("Installing DattoRMM (Priority 2)...", "cyan");
try {
const DattoRMMCheckbox = document.querySelectorAll('input[name="dattoRMMOption"]:checked');
const checkedValues = Array.from(DattoRMMCheckbox).map(c => c.value);
const dropdown = document.getElementById('dattoRmmDropdown');
const UID = dropdown && dropdown.value ? dropdown.value : null;
const Name = dropdown && dropdown.options[dropdown.selectedIndex] ? dropdown.options[dropdown.selectedIndex].text : null;
const payload = { checkedValues, UID, Name };
await fetch('/installrmm', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
appendLog("DattoRMM installation completed.", "green");
} catch (error) {
appendLog("Error installing DattoRMM: " + error.message, "red");
}
}
if (document.querySelector('input[name="setSVSPowerplan"]').checked) {
appendLog("Setting SVS Powerplan (Priority 3)...", "cyan");
try {
await fetch('/setSVSPowerplan', { method: 'GET' });
appendLog("SVS Powerplan set successfully.", "green");
} catch (error) {
appendLog("Error setting SVS Powerplan: " + error.message, "red");
}
}
if (document.querySelector('input[name="installCyberQP"]').checked) {
appendLog("Installing CyberQP (Priority 3)...", "cyan");
try {
await fetch('/installCyberQP', { method: 'GET' });
appendLog("CyberQP installation completed.", "green");
} catch (error) {
appendLog("Error installing CyberQP: " + error.message, "red");
}
}
if (document.querySelector('input[name="installSplashtop"]').checked) {
appendLog("Installing Splashtop (Priority 3)...", "cyan");
try {
await fetch('/installSplashtop', { method: 'GET' });
appendLog("Splashtop installation completed.", "green");
} catch (error) {
appendLog("Error installing Splashtop: " + error.message, "red");
}
}
if (document.querySelector('input[name="installSVSHelpDesk"]').checked) {
appendLog("Installing SVS HelpDesk (Priority 3)...", "cyan");
try {
await fetch('/installSVSHelpDesk', { method: 'GET' });
appendLog("SVS HelpDesk installation completed.", "green");
} catch (error) {
appendLog("Error installing SVS HelpDesk: " + error.message, "red");
}
}
if (document.querySelector('input[name="installThreatLocker"]').checked) {
appendLog("Installing ThreatLocker (Priority 3)...", "cyan");
try {
await fetch('/installThreatLocker', { method: 'GET' });
appendLog("ThreatLocker installation completed.", "green");
} catch (error) {
appendLog("Error installing ThreatLocker: " + error.message, "red");
}
}
if (document.querySelector('input[name="installRocketCyber"]').checked) {
appendLog("Installing RocketCyber (Priority 3)...", "cyan");
try {
await fetch('/installRocketCyber', { method: 'GET' });
appendLog("RocketCyber installation completed.", "green");
} catch (error) {
appendLog("Error installing RocketCyber: " + error.message, "red");
}
}
if (document.querySelector('input[name="setedgedefaultsearch"]').checked) {
appendLog("Setting Edge Default Search Engine (Priority 3)...", "cyan");
try {
await fetch('/setedgedefaultsearch', { method: 'GET' });
appendLog("Edge Default Search Engine set successfully.", "green");
} catch (error) {
appendLog("Error setting Edge Default Search Engine: " + error.message, "red");
}
}
if (document.querySelector('input[name="EnableBitLocker"]').checked) {
appendLog("Enabling BitLocker (Priority 3)...", "cyan");
try {
await fetch('/EnableBitLocker', { method: 'GET' });
appendLog("BitLocker enabled successfully.", "green");
} catch (error) {
appendLog("Error enabling BitLocker: " + error.message, "red");
}
}
};
// Steph's Pick trigger
window.triggerStephsPick = function() {
const packages = [];
if (document.getElementById('installAppleiCloudCheckbox').checked) {
packages.push("Apple.iCloud");
}
if (document.getElementById('installObsidianCheckbox').checked) {
packages.push("Obsidian.Obsidian");
}
if (document.getElementById('installFlameshotCheckbox').checked) {
packages.push("Flameshot.Flameshot");
}
if (document.getElementById('installSublimeTextCheckbox').checked) {
packages.push("SublimeHQ.SublimeText.4");
}
if (packages.length === 0) {
appendLog("Please select at least one package to install.", "red");
return;
}
appendLog("Installing Steph's Pick packages: " + packages.join(", "), "cyan");
fetch('/installStephsPick', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ packages: packages })
})
.then(response => {
if (!response.ok) {
throw new Error("Failed to install Steph's Pick packages.");
}
return response.text();
})
.then(message => {
appendLog(message, "green");
})
.catch(error => {
appendLog("Error: " + error.message, "red");
});
};
// End session
window.endSession = function() {
appendLog("Session ended. Closing application...", "yellow");
fetch('/quit', { method: 'GET' })
.then(response => {
if (!response.ok) {
throw new Error('Failed to end session');
}
window.close();
})
.catch(error => {
appendLog("Error ending session: " + error.message, "red");
});
};
// Append log messages
window.appendLog = function(message, color = "white") {
const log = document.createElement('p');
log.style.color = color;
log.textContent = message;
document.getElementById('logArea').appendChild(log);
};
// Poll server logs every 3 seconds
let lastLogCount = 0;
async function fetchLogs() {
try {
const resp = await fetch('/getLogs');
if (!resp.ok) return;
const logs = await resp.json();
for (let i = lastLogCount; i < logs.length; i++) {
appendLog(logs[i].Message, "white");
}
lastLogCount = logs.length;
} catch (err) {
console.error("Error fetching logs:", err);
}
}
setInterval(fetchLogs, 3000);
}); // End DOMContentLoaded
</script>
</body>
</html>
"@
}
Start-Process "msedge.exe" -ArgumentList "--app=http://localhost:8081/"
try {
while ($listener.IsListening) {
$context = $listener.GetContext()
$request = $context.Request
$response = $context.Response
switch ($request.Url.AbsolutePath) {
"/" {
$htmlContent = GetHtmlContent
$buffer = [System.Text.Encoding]::UTF8.GetBytes($htmlContent)
$response.ContentType = "text/html"
$response.ContentLength64 = $buffer.Length
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
}
"/getn8npw" {
if ($request.HttpMethod -eq "POST") {
try {
$bodyStream = New-Object IO.StreamReader $request.InputStream
$body = $bodyStream.ReadToEnd()
$data = ConvertFrom-Json $body
$password = $data.password
Get-N8nWebhookData -AuthHeaderValue $password
$sites = Install-DattoRMM-Helper -ApiUrl $ApiUrl -ApiKey $ApiKey -ApiSecretKey $ApiSecretKey -FetchSitesOnly
if (-not $sites) {
Write-Host "No sites returned. Please check the API." -ForegroundColor Red
$response.StatusCode = 500
$buffer = [System.Text.Encoding]::UTF8.GetBytes("No sites found")
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
continue
}
$responseData = $sites | ConvertTo-Json
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseData)
$response.ContentType = "application/json"
$response.ContentLength64 = $buffer.Length
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
} catch {
Write-LogHybrid -Message "Error processing /getn8npw: $($_.Exception.Message)" -Level "Error"
$response.StatusCode = 500
$buffer = [System.Text.Encoding]::UTF8.GetBytes("Error: Failed to process the request.")
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
}
}
}
"/installSVSMSPModule" {
if ($request.HttpMethod -eq "GET") {
try {
Install-SVSMSP -InstallToolkit
$responseString = "Install SVSMSP Module triggered successfully."
$response.StatusCode = 200
} catch {
$responseString = "Error triggering Install SVSMSP Module: $_"
$response.StatusCode = 500
}
} else {
$responseString = "Method not allowed. Use GET."
$response.StatusCode = 405
}
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
$response.ContentType = "text/plain"
$response.ContentLength64 = $buffer.Length
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
}
"/installrmm" {
if ($request.HttpMethod -eq "POST") {
try {
$bodyStream = New-Object IO.StreamReader $request.InputStream
$body = $bodyStream.ReadToEnd()
$requestData = ConvertFrom-Json $body
$checkedValues = $requestData.checkedValues
$UID = $requestData.UID
$Name = $requestData.Name
if (-not $checkedValues -or -not $UID -or -not $Name) {
Write-LogHybrid -Message "Invalid input received. Missing required parameters: UID, Name, or checkbox values." -Level "Error"
$response.StatusCode = 400
$responseString = "Error: Missing required input parameters."
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
return
}
$installRMMCommand = "Install-DattoRMM -ApiUrl '$ApiUrl' -ApiKey '$ApiKey' -ApiSecretKey '$ApiSecretKey' -SiteName $Name -SiteUID $UID "
if ($checkedValues -contains 'inputVar') {
$installRMMCommand += " -PushSiteVars"
}
if ($checkedValues -contains 'rmm') {
$installRMMCommand += " -InstallRMM"
}
if ($checkedValues -contains 'exe') {
$installRMMCommand += " -SaveCopy"
}
try {
Invoke-Expression $installRMMCommand
$responseString = "RMM installation triggered successfully for $Name."
Write-LogHybrid -Message $responseString -Level "Success"
$response.StatusCode = 200
} catch {
$responseString = "Error triggering RMM installation: $($_.Exception.Message)"
Write-LogHybrid -Message $responseString -Level "Error"
$response.StatusCode = 500
}
} catch {
$errorString = "An error occurred while processing the /installrmm request: $($_.Exception.Message)"
Write-LogHybrid -Message $errorString -Level "Error"
$response.StatusCode = 500
$responseString = $errorString
}
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
$response.ContentType = "text/plain"
$response.ContentLength64 = $buffer.Length
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
} else {
$response.StatusCode = 405
$response.StatusDescription = "Method Not Allowed"
$responseString = "Error: Only POST requests are allowed."
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
}
}
"/setSVSPowerplan" {
if ($request.HttpMethod -eq "GET") {
try {
Set-SVSPowerPlan
$responseString = "Setting SVS PowerPlan triggered successfully."
$response.StatusCode = 200
} catch {
$responseString = "Error triggering Setting SVS PowerPlan: $_"
$response.StatusCode = 500
}
} else {
$responseString = "Method not allowed. Use GET."
$response.StatusCode = 405
}
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
$response.ContentType = "text/plain"
$response.ContentLength64 = $buffer.Length
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
}
"/installCyberQP" {
if ($request.HttpMethod -eq "GET") {
try {
Install-CyberQP
$responseString = "Install CyberQP triggered successfully."
$response.StatusCode = 200
} catch {
$responseString = "Error triggering Install CyberQP: $_"
$response.StatusCode = 500
}
} else {
$responseString = "Method not allowed. Use GET."
$response.StatusCode = 405
}
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
$response.ContentType = "text/plain"
$response.ContentLength64 = $buffer.Length
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
}
"/installSplashtop" {
if ($request.HttpMethod -eq "GET") {
try {
Install-Splashtop
$responseString = "Install Splashtop triggered successfully."
$response.StatusCode = 200
} catch {
$responseString = "Error triggering Install Splashtop: $_"
$response.StatusCode = 500
}
} else {
$responseString = "Method not allowed. Use GET."
$response.StatusCode = 405
}
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
$response.ContentType = "text/plain"
$response.ContentLength64 = $buffer.Length
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
}
"/installRocketCyber" {
if ($request.HttpMethod -eq "GET") {
try {
Install-RocketCyber
$responseString = "Install RocketCyber triggered successfully."
$response.StatusCode = 200
} catch {
$responseString = "Error triggering Install RocketCyber: $_"
$response.StatusCode = 500
}
} else {
$responseString = "Method not allowed. Use GET."
$response.StatusCode = 405
}
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
$response.ContentType = "text/plain"
$response.ContentLength64 = $buffer.Length
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
}
"/installThreatLocker" {
if ($request.HttpMethod -eq "GET") {
try {
Install-ThreatLocker
$responseString = "Install ThreatLocker triggered successfully."
$response.StatusCode = 200
} catch {
$responseString = "Error triggering Install ThreatLocker: $_"
$response.StatusCode = 500
}
} else {
$responseString = "Method not allowed. Use GET."
$response.StatusCode = 405
}
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
$response.ContentType = "text/plain"
$response.ContentLength64 = $buffer.Length
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
}
"/setedgedefaultsearch" {
if ($request.HttpMethod -eq "GET") {
try {
set-EdgeDefaultSearchProvider
$responseString = "setedgedefaultsearch triggered successfully."
$response.StatusCode = 200
} catch {
$responseString = "Error triggering setedgedefaultsearch: $_"
$response.StatusCode = 500
}
} else {
$responseString = "Method not allowed. Use GET."
$response.StatusCode = 405
}
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
$response.ContentType = "text/plain"
$response.ContentLength64 = $buffer.Length
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
}
"/installSVSHelpDesk" {
if ($request.HttpMethod -eq "GET") {
try {
Install-SVSHelpDesk
$responseString = "Install SVSHelpDesk triggered successfully."
$response.StatusCode = 200
} catch {
$responseString = "Error triggering Install SVSHelpDesk: $_"
$response.StatusCode = 500
}
} else {
$responseString = "Method not allowed. Use GET."
$response.StatusCode = 405
}
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
$response.ContentType = "text/plain"
$response.ContentLength64 = $buffer.Length
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
}
"/EdgeDefaultSearchEngine" {
if ($request.HttpMethod -eq "GET") {
try {
Write-LogHybrid -Message "Setting Edge Default Search Engine started." -Level "Info"
Set-EdgeDefaultSearchEngine
Write-LogHybrid -Message "Edge Default Search Engine set successfully." -Level "Success"
$responseString = "Edge Default Search Engine triggered successfully."
$response.StatusCode = 200
} catch {
Write-LogHybrid -Message "Error setting Edge Default Search Engine: $($_.Exception.Message)" -Level "Error"
$responseString = "Error attempting to set Edge Default Search Engine: $_"
$response.StatusCode = 500
}
} else {
$responseString = "Method not allowed. Use GET."
$response.StatusCode = 405
}
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
$response.ContentType = "text/plain"
$response.ContentLength64 = $buffer.Length
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
}
"/EnableBitLocker" {
if ($request.HttpMethod -eq "GET") {
try {
Set-SVSBitLocker -Mode Enable -DriveLetter C -SaveToRegistry $true
$responseString = "BitLocker enabled on C successfully."
$response.StatusCode = 200
} catch {
$responseString = "Error Attempting to set BitLocker: $_"
$response.StatusCode = 500
}
} else {
$responseString = "Method not allowed. Use GET."
$response.StatusCode = 405
}
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
$response.ContentType = "text/plain"
$response.ContentLength64 = $buffer.Length
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
}
# Steph's Pick Route
"/installStephsPick" {
if ($request.HttpMethod -eq "POST") {
try {
$bodyStream = New-Object IO.StreamReader $request.InputStream
$body = $bodyStream.ReadToEnd()
$data = ConvertFrom-Json $body
$selectedPackages = $data.packages
if (-not $selectedPackages -or $selectedPackages.Count -eq 0) {
$selectedPackages = @("Apple.iCloud", "Obsidian.Obsidian", "Flameshot.Flameshot", "SublimeHQ.SublimeText.4")
}
Install-StephsPick -Packages $selectedPackages
$responseString = "Steph's Pick installation triggered successfully."
$response.StatusCode = 200
}
catch {
$responseString = "Error triggering Steph's Pick installation: $($_.Exception.Message)"
$response.StatusCode = 500
}
}
else {
$responseString = "Method not allowed. Use POST."
$response.StatusCode = 405
}
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
$response.ContentType = "text/plain"
$response.ContentLength64 = $buffer.Length
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
}
"/offboard" {
if ($request.HttpMethod -eq "POST") {
try {
$bodyStream = New-Object IO.StreamReader $request.InputStream
$body = $bodyStream.ReadToEnd()
$requestData = ConvertFrom-Json $body
$selectedTasks = $requestData.SelectedTasks
Write-LogHybrid -Message "Offboarding request received with tasks: $($selectedTasks -join ', ')" -Level "Info"
if (-not $selectedTasks -or $selectedTasks.Count -eq 0) {
$response.StatusCode = 400
$responseString = "Error: No offboarding tasks selected."
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
return
}
foreach ($task in $selectedTasks) {
switch ($task) {
"uninstallSVSMSPModule" { Write-LogHybrid -Message "Uninstalling SVSMSP Module..." -Level "Info"; Install-SVSMSP -cleanup }
"uninstallThreatLocker" { Write-LogHybrid -Message "Uninstalling Threatlocker" -Level "Info"; Uninstall-ThreatLocker }
"uninstallCyberQP" { Write-LogHybrid -Message "Uninstalling CyberQP" -Level "Info"; Uninstall-CyberQP }
"uninstallDattoEDR" { Uninstall-DattoEDR }
"uninstallDattoRMM" { Uninstall-DattoRMM }
"uninstallRocketCyber" { Uninstall-RocketCyber }
"uninstallSplashtop" { Uninstall-Splashtop }
"uninstallSVSHelpdesk" { Uninstall-SVSHelpdesk }
"uninstallSVSWatchtower" { Uninstall-SVSWatchtower }
default { Write-LogHybrid -Message "Unknown task: $task" -Level "Warning" }
}
}
$responseString = "Offboarding tasks executed successfully."
$response.StatusCode = 200
} catch {
$responseString = "Error processing offboarding tasks: $($_.Exception.Message)"
$response.StatusCode = 500
}
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
$response.ContentType = "text/plain"
$response.ContentLength64 = $buffer.Length
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
} else {
$responseString = "Method not allowed. Use POST."
$response.StatusCode = 405
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
}
}
"/runTweaks" {
if ($request.HttpMethod -eq "POST") {
try {
$bodyStream = New-Object IO.StreamReader $request.InputStream
$body = $bodyStream.ReadToEnd()
$requestData = ConvertFrom-Json $body
$tweaks = $requestData.tweaks
if (-not $tweaks -or $tweaks.Count -eq 0) {
$response.StatusCode = 400
$responseString = "Error: No tweaks selected."
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
return
}
foreach ($tweak in $tweaks) {
switch ($tweak) {
"enableDarkModeCheckbox" {
Write-LogHybrid -Message "Running tweak: Set Edge Default Search Engine" -Level "Info"
Set-EdgeDefaultSearchEngine
}
"disableAnimationsCheckbox" {
Write-LogHybrid -Message "Running tweak: Disable Animations" -Level "Info"
}
"optimizePerformanceCheckbox" {
Write-LogHybrid -Message "Running tweak: Optimize Performance" -Level "Info"
}
"increaseFontSizeCheckbox" {
Write-LogHybrid -Message "Running tweak: Increase Font Size" -Level "Info"
}
default { Write-LogHybrid -Message "Unknown tweak: $tweak" -Level "Warning" }
}
}
$responseString = "Selected tweaks executed successfully."
$response.StatusCode = 200
} catch {
$responseString = "Error processing tweaks: $($_.Exception.Message)"
$response.StatusCode = 500
}
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
$response.ContentType = "text/plain"
$response.ContentLength64 = $buffer.Length
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
} else {
$responseString = "Method not allowed. Use POST."
$response.StatusCode = 405
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
}
}
"/getLogs" {
if ($request.HttpMethod -eq "GET") {
$jsonLogs = $Global:LogCache | ConvertTo-Json
$logBuffer = [System.Text.Encoding]::UTF8.GetBytes($jsonLogs)
$response.ContentType = "application/json"
$response.ContentLength64 = $logBuffer.Length
$response.OutputStream.Write($logBuffer, 0, $logBuffer.Length)
$response.OutputStream.Close()
}
}
"/quit" {
if ($request.HttpMethod -eq "GET") {
$responseString = "Server shutting down."
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
$response.ContentType = "text/plain"
$response.ContentLength64 = $buffer.Length
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
Write-Host $responseString
$listener.Stop()
break
}
}
default {
$response.StatusCode = 404
$response.StatusDescription = "Not Found"
$buffer = [System.Text.Encoding]::UTF8.GetBytes("404 - Not Found")
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
}
}
}
}
catch {
Write-Host "Error: $($_.Exception.Message)"
}
finally {
if ($listener -ne $null) {
try {
Write-LogHybrid -Message "Stopping the listener." -Level "Info"
$listener.Stop()
$listener.Close()
Write-LogHybrid -Message "Listener stopped successfully." -Level "Info"
} catch {
Write-LogHybrid -Message "Error stopping the listener: $($_.Exception.Message)" -Level "Error"
}
} else {
Write-LogHybrid -Message "Listener object is null; nothing to stop." -Level "Warning"
}
}