-
On-Boarding
-This new deployment method ensures everything is successfully deployed with greater ease!
-
-
-
SVSMSP Stack
- - - - - - - - - -
-
-
-
-
+
+
+
-
-
-
+
+
+
+
+
+
+
-
+
- On-Boarding
+This new deployment method ensures everything is successfully deployed with greater ease!
+ +
+
+
-
+
+
+
+ SVSMSP Stack
+ + + + + + + + + +
+
+
+
+
+
+ +
+
Optional
+ + + +
-
- Optional
- - -
-
- -
- - -
-
-
- -
- - -
-
-
-
-
-
-
-
- Off-Boarding
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Tweaks
-
-
-
- System Optimizations
-
-
-
-
+
-
-
-
-
-
-
+
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+
+
+
-
-
- Additional Tweaks
-
-
-
-
+
+
-
+
- Off-Boarding
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
- Miscellaneous
-
-
-
+
-
+
- Tweaks
+
+
+
+
+
+
+
+
+ System Optimizations
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Additional Tweaks
+
+
+
+
+
+
+
+ Miscellaneous
+
+
+
+
+
+
+
-
-
-
-
-
+ function toggleRadioButtons(checkbox) {
+ const radioGroup = document.getElementById("windowsPerformanceOptions");
+ if (checkbox.checked) {
+ radioGroup.style.display = "block";
+ } else {
+ radioGroup.style.display = "none";
+ // Optionally, reset the radio buttons to their default state
+ const radios = radioGroup.querySelectorAll('input[type="radio"]');
+ radios.forEach(radio => {
+ radio.checked = false;
+ });
+ radios[2].checked = true; // Reset to "None"
+ }
+ }
+
+ function triggerTweaks() {
+ // Get the state of the checkboxes
+ const setEdgeDefaultSearch = document.getElementById('setedgedefaultsearchCheckbox').checked;
+ const optimizeWindowsPerformance = document.getElementById('setWindowsPerformanceCheckbox').checked;
+ const stopUnnecessaryServices = document.getElementById('stopUnnecessaryServicesCheckbox').checked;
+ const disableAnimations = document.getElementById('disableAnimationsCheckbox').checked;
+ const optimizePerformance = document.getElementById('optimizePerformanceCheckbox').checked;
+ const increaseFontSize = document.getElementById('increaseFontSizeCheckbox').checked;
+ const enableDarkMode = document.getElementById('enableDarkModeCheckbox').checked;
+ const clearTempFiles = document.getElementById('clearTempFilesCheckbox').checked;
+
+ // Get the selected radio button for Windows Performance Optimization
+ let optimizeWindowsPerformanceLevel = "none";
+ if (optimizeWindowsPerformance) {
+ const radios = document.querySelectorAll('input[name="optimizeWindowsPerformanceLevel"]');
+ radios.forEach(radio => {
+ if (radio.checked) {
+ optimizeWindowsPerformanceLevel = radio.value;
+ }
+ });
+ }
+
+ // Log or handle the tweaks (replace console.log with actual logic as needed)
+ console.log("Set Edge Default Search Engine:", setEdgeDefaultSearch);
+ console.log("Optimize Windows Performance:", optimizeWindowsPerformance);
+ console.log("Windows Performance Optimization Level:", optimizeWindowsPerformanceLevel);
+ console.log("Stop Unnecessary Services:", stopUnnecessaryServices);
+ console.log("Disable Animations:", disableAnimations);
+ console.log("Optimize Application Performance:", optimizePerformance);
+ console.log("Increase Font Size:", increaseFontSize);
+ console.log("Enable Dark Mode:", enableDarkMode);
+ console.log("Clear Temporary Files:", clearTempFiles);
+
+ // Example: Apply tweaks (replace these comments with actual implementations)
+ if (setEdgeDefaultSearch) {
+ // Call function or API to set Edge default search engine
+ }
+
+ if (optimizeWindowsPerformance) {
+ if (optimizeWindowsPerformanceLevel === "full") {
+ // Apply full optimization
+ } else if (optimizeWindowsPerformanceLevel === "partial") {
+ // Apply partial optimization
+ } else {
+ // No optimization
+ }
+ }
+
+ if (stopUnnecessaryServices) {
+ // Stop unnecessary services
+ }
+
+ if (disableAnimations) {
+ // Disable animations in the system
+ }
+
+ if (optimizePerformance) {
+ // Optimize application performance
+ }
+
+ if (increaseFontSize) {
+ // Increase font size
+ }
+
+ if (enableDarkMode) {
+ // Enable dark mode
+ }
+
+ if (clearTempFiles) {
+ // Clear temporary files
+ }
+
+ // Notify user tweaks are applied
+ alert("Tweaks applied successfully!");
+ }
+
+ function toggleDattoRMMOptions() {
+ 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"]');
+
+ // Toggle visibility of sub-options
+ if (dattoRMMCheckbox.checked) {
+ optionsContainer.style.display = 'block';
+ n8nPasswordContainer.style.display = 'block';
+ dattoRMMContainer.style.display = 'block';
+
+ // Automatically check sub-checkboxes
+ subCheckboxes.forEach(subCheckbox => {
+ subCheckbox.checked = true;
+ });
+ } else {
+ optionsContainer.style.display = 'none';
+ n8nPasswordContainer.style.display = 'none';
+ dattoRMMContainer.style.display = 'none';
+
+ // Automatically uncheck sub-checkboxes
+ subCheckboxes.forEach(subCheckbox => {
+ subCheckbox.checked = false;
+ });
+ }
+ }
+
+
+ const tabButtons = document.querySelectorAll('.tab-button');
+ const tabContents = document.querySelectorAll('.tab-content');
+ const logArea = document.getElementById('logArea');
+ const fetchSitesButton = document.getElementById('fetchSitesButton');
+ const n8nPasswordInput = document.getElementById('n8nPassword');
+
+ 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');
+ });
+ });
+
+ n8nPasswordInput.addEventListener('input', () => {
+ fetchSitesButton.disabled = n8nPasswordInput.value.length < 4;
+ });
+ // Trigger fetchSites() on Enter key press
+ n8nPasswordInput.addEventListener('keydown', (event) => {
+ if (event.key === 'Enter' && n8nPasswordInput.value.length >= 12) {
+ fetchSites(); // Call the fetchSites function
+ }
+ });
+
+ async function fetchSites() {
+ const password = document.getElementById('n8nPassword').value;
+ const dropdown = document.getElementById('dattoRmmDropdown');
+
+ if (!password) {
+ appendLog("Please enter the n8n password.", "red");
+ return;
+ }
+
+ try {
+ appendLog("Fetching sites...", "yellow");
+
+ const response = await fetch('/getn8npw', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ password })
+ });
+
+ if (!response.ok) {
+ throw new Error('Failed to fetch sites. Please try again.');
+ }
+
+ const sites = await response.json();
+ dropdown.innerHTML = '';
+
+ sites.forEach(site => {
+ const option = document.createElement('option');
+ // Adjust property names based on your actual data
+ option.value = site.UID;
+ option.textContent = site.Name;
+ dropdown.appendChild(option);
+ });
+
+ appendLog("Sites fetched successfully, please select a site!", "green");
+ }
+ catch (error) {
+ dropdown.innerHTML = '';
+ appendLog('Error:' + error.message, "red");
+ }
+ }
+
+ function triggerInstall() {
+ const dropdown = document.getElementById('dattoRmmDropdown');
+ const UID = dropdown && dropdown.options[dropdown.selectedIndex]
+ ? dropdown.options[dropdown.selectedIndex].value
+ : null;
+ const Name = dropdown && dropdown.options[dropdown.selectedIndex]
+ ? dropdown.options[dropdown.selectedIndex].text
+ : null;
+
+ (async () => {
+ // Priority 1: Install SVSMSP Module
+ if (document.querySelector('input[name="installSVSMSPModule"]').checked) {
+ appendLog("Installing SVSMSP Module (Priority 1)...", "cyan");
+ try {
+ await fetch('/installSVSMSPModule', { method: 'GET' });
+ appendLog("SVSMSP Module installation completed.", "green");
+ } catch (error) {
+ appendLog("Error installing SVSMSP Module: " + error.message, "red");
+ }
+ }
+
+ // Priority 2: Install DattoRMM
+ 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 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");
+ }
+ }
+
+ // Priority 3: Other tasks
+ 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");
+ }
+ }
+
+ // NEW: Set Edge Default Search Engine
+ 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");
+ }
+ }
+
+ })();
+ }
+
+
+
+
+
+ function endSession() {
+ 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");
+ });
+ }
+
+ // Intercept window close or refresh
+ window.addEventListener('beforeunload', (event) => {
+ endSession(); // Clean up on window close
+
+ });
+
+
+
+
+
+
+ function appendLog(message, color = "white") {
+ const log = document.createElement('p');
+ log.style.color = color;
+ log.textContent = message;
+ document.getElementById('logArea').appendChild(log);
+ }
+
+
+ // -------------------------------------------------------------------
+ // 3) POLL THE SERVER LOGS (NEW)
+ // -------------------------------------------------------------------
+ let lastLogCount = 0;
+ async function fetchLogs() {
+ try {
+ const resp = await fetch('/getLogs');
+ if (!resp.ok) return;
+ const logs = await resp.json(); // array of {Timestamp, Level, Message}
+
+ // Append only new messages
+ for (let i = lastLogCount; i < logs.length; i++) {
+ // We'll display each new line in "white" or a color of your choice
+ appendLog(logs[i].Message, "white");
+ }
+ lastLogCount = logs.length;
+ } catch (err) {
+ console.error("Error fetching logs:", err);
+ }
+ }
+ // Poll logs every 3 seconds (feel free to adjust)
+ setInterval(fetchLogs, 3000);
+ // -------------------------------------------------------------------
+
"@
}
+
+
+# Save and launch the HTML
Start-Process "msedge.exe" -ArgumentList "--app=http://localhost:8081/"
+
try {
while ($listener.IsListening) {
+ ### Process Incoming Requests
+ # - `$context`: Contains the request and response objects.
+ # - `$request`: Represents the HTTP request.
+ # - `$response`: Represents the HTTP response.
$context = $listener.GetContext()
$request = $context.Request
$response = $context.Response
+
+ ### Route Handling
+ # - Routes are matched based on the `AbsolutePath` of the request URL.
+ # - Each route corresponds to a specific action or task.
switch ($request.Url.AbsolutePath) {
+
+ # ----------------------------------------------------------------
+ # ROOT ROUTE ("/")
+ # Serves the main HTML GUI to the client.
+ # ----------------------------------------------------------------
"/" {
$htmlContent = GetHtmlContent
$buffer = [System.Text.Encoding]::UTF8.GetBytes($htmlContent)
@@ -1143,15 +1457,24 @@ try {
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
}
+
+ # ----------------------------------------------------------------
+ # ROUTE: /getn8npw
+ # Fetches the n8n password and retrieves DattoRMM site details.
+ # ----------------------------------------------------------------
"/getn8npw" {
if ($request.HttpMethod -eq "POST") {
try {
+ # Parse the JSON body to extract the password.
$bodyStream = New-Object IO.StreamReader $request.InputStream
- $body = $bodyStream.ReadToEnd()
- $data = ConvertFrom-Json $body
- $password = $data.password
+ $body = $bodyStream.ReadToEnd()
+ $data = ConvertFrom-Json $body
+ $password = $data.password
+
+ # Call the webhook to fetch site details.
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
@@ -1160,13 +1483,15 @@ try {
$response.OutputStream.Close()
continue
}
+
+ # Return site details as JSON.
$responseData = $sites | ConvertTo-Json
- $buffer = [System.Text.Encoding]::UTF8.GetBytes($responseData)
- $response.ContentType = "application/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 {
+ }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.")
@@ -1175,6 +1500,7 @@ try {
}
}
}
+
"/installSVSMSPModule" {
if ($request.HttpMethod -eq "GET") {
try {
@@ -1194,16 +1520,23 @@ try {
$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
+ # Step 1: Read the Request Body
+ $bodyStream = New-Object IO.StreamReader $request.InputStream
+ $body = $bodyStream.ReadToEnd()
+ $requestData = ConvertFrom-Json $body
+
+ # Step 2: Extract Data from the Request
$checkedValues = $requestData.checkedValues
- $UID = $requestData.UID
- $Name = $requestData.Name
+ $UID = $requestData.UID
+ $Name = $requestData.Name
+
+ # Step 3: Validate Input
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
@@ -1213,7 +1546,10 @@ try {
$response.OutputStream.Close()
return
}
+
+ # Step 4: Build the PowerShell Command Dynamically
$installRMMCommand = "Install-DattoRMM -ApiUrl '$ApiUrl' -ApiKey '$ApiKey' -ApiSecretKey '$ApiSecretKey' -SiteName $Name -SiteUID $UID "
+
if ($checkedValues -contains 'inputVar') {
$installRMMCommand += " -PushSiteVars"
}
@@ -1223,6 +1559,10 @@ try {
if ($checkedValues -contains 'exe') {
$installRMMCommand += " -SaveCopy"
}
+
+
+
+ # Step 5: Execute the Command
try {
Invoke-Expression $installRMMCommand
$responseString = "RMM installation triggered successfully for $Name."
@@ -1234,17 +1574,21 @@ try {
$response.StatusCode = 500
}
} catch {
+ # Log General Errors
$errorString = "An error occurred while processing the /installrmm request: $($_.Exception.Message)"
Write-LogHybrid -Message $errorString -Level "Error"
$response.StatusCode = 500
$responseString = $errorString
}
+
+ # Step 6: Return the Response
$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 {
+ # Handle Invalid HTTP Methods
$response.StatusCode = 405
$response.StatusDescription = "Method Not Allowed"
$responseString = "Error: Only POST requests are allowed."
@@ -1253,9 +1597,13 @@ try {
$response.OutputStream.Close()
}
}
+
+
+
"/setSVSPowerplan" {
if ($request.HttpMethod -eq "GET") {
- try {
+
+ try {
Set-SVSPowerPlan
$responseString = "Setting SVS PowerPlan triggered successfully."
$response.StatusCode = 200
@@ -1267,12 +1615,14 @@ try {
$responseString = "Method not allowed. Use GET."
$response.StatusCode = 405
}
- $buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
- $response.ContentType = "text/plain"
+ $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 {
@@ -1292,10 +1642,12 @@ try {
$response.ContentLength64 = $buffer.Length
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
+
}
+
"/installSplashtop" {
if ($request.HttpMethod -eq "GET") {
- try {
+ try {
Install-Splashtop
$responseString = "Install Splashtop triggered successfully."
$response.StatusCode = 200
@@ -1308,172 +1660,158 @@ try {
$response.StatusCode = 405
}
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
- $response.ContentType = "text/plain"
+ $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
+ 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
}
- } else {
- $responseString = "Method not allowed. Use GET."
- $response.StatusCode = 405
- }
- $buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
- $response.ContentType = "text/plain"
+ $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
+ 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
}
- } else {
- $responseString = "Method not allowed. Use GET."
- $response.StatusCode = 405
- }
- $buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
- $response.ContentType = "text/plain"
+ $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" {
+
+ "/setedgedefaultsearch"{
if ($request.HttpMethod -eq "GET") {
- try {
- set-EdgeDefaultSearchProvider
- $responseString = "setedgedefaultsearch triggered successfully."
- $response.StatusCode = 200
- } catch {
- $responseString = "Error triggering setedgedefaultsearch: $_"
- $response.StatusCode = 500
+ try {
+ set-EdgeDefaultSearchProvider
+ $responseString = "setedgedefaultsearch triggered successfully."
+ $response.StatusCode = 200
+ } catch {
+ $responseString = "Error triggering Install ThreatLocker: $_"
+ $response.StatusCode = 500
+ }
+ } else {
+ $responseString = "Method not allowed. Use GET."
+ $response.StatusCode = 405
}
- } else {
- $responseString = "Method not allowed. Use GET."
- $response.StatusCode = 405
- }
- $buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
- $response.ContentType = "text/plain"
+ $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
+ 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
}
- } else {
- $responseString = "Method not allowed. Use GET."
- $response.StatusCode = 405
- }
- $buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
- $response.ContentType = "text/plain"
+ $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
+ 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 = " Set 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
}
- } else {
- $responseString = "Method not allowed. Use GET."
- $response.StatusCode = 405
- }
- $buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
- $response.ContentType = "text/plain"
+ $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")
+ 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
}
- Install-StephsPick -Packages $selectedPackages
- $responseString = "Steph's Pick installation triggered successfully."
- $response.StatusCode = 200
+ } else {
+ $responseString = "Method not allowed. Use GET."
+ $response.StatusCode = 405
}
- 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"
+ $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
+ # Read the Request Body
+ $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."
@@ -1482,26 +1820,34 @@ try {
$response.OutputStream.Close()
return
}
+
+ # Process each selected task
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 }
+ "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" }
+ default {
+ Write-LogHybrid -Message "Unknown task: $task" -Level "Warning"
+ }
}
}
+
+ # Return Success Response
$responseString = "Offboarding tasks executed successfully."
$response.StatusCode = 200
} catch {
$responseString = "Error processing offboarding tasks: $($_.Exception.Message)"
$response.StatusCode = 500
}
+
+ # Send the Response
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
$response.ContentType = "text/plain"
$response.ContentLength64 = $buffer.Length
@@ -1515,12 +1861,17 @@ try {
$response.OutputStream.Close()
}
}
+
+
"/runTweaks" {
if ($request.HttpMethod -eq "POST") {
try {
- $bodyStream = New-Object IO.StreamReader $request.InputStream
- $body = $bodyStream.ReadToEnd()
- $requestData = ConvertFrom-Json $body
+ # Step 1: Read the Request Body
+ $bodyStream = New-Object IO.StreamReader $request.InputStream
+ $body = $bodyStream.ReadToEnd()
+ $requestData = ConvertFrom-Json $body
+
+ # Step 2: Validate Input
$tweaks = $requestData.tweaks
if (-not $tweaks -or $tweaks.Count -eq 0) {
$response.StatusCode = 400
@@ -1530,6 +1881,8 @@ try {
$response.OutputStream.Close()
return
}
+
+ # Step 3: Run Selected Tweaks
foreach ($tweak in $tweaks) {
switch ($tweak) {
"enableDarkModeCheckbox" {
@@ -1538,22 +1891,31 @@ try {
}
"disableAnimationsCheckbox" {
Write-LogHybrid -Message "Running tweak: Disable Animations" -Level "Info"
+ #Disable-Animations
}
"optimizePerformanceCheckbox" {
Write-LogHybrid -Message "Running tweak: Optimize Performance" -Level "Info"
+ #Optimize-Performance
}
"increaseFontSizeCheckbox" {
Write-LogHybrid -Message "Running tweak: Increase Font Size" -Level "Info"
+ #Increase-FontSize
+ }
+ default {
+ Write-LogHybrid -Message "Unknown tweak: $tweak" -Level "Warning"
}
- default { Write-LogHybrid -Message "Unknown tweak: $tweak" -Level "Warning" }
}
}
+
+ # Step 4: Return Success Response
$responseString = "Selected tweaks executed successfully."
$response.StatusCode = 200
} catch {
$responseString = "Error processing tweaks: $($_.Exception.Message)"
$response.StatusCode = 500
}
+
+ # Send the Response
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
$response.ContentType = "text/plain"
$response.ContentLength64 = $buffer.Length
@@ -1567,6 +1929,12 @@ try {
$response.OutputStream.Close()
}
}
+
+
+ # ----------------------------------------------------------------
+ # 4) NEW ROUTE: /getLogs
+ # Returns $Global:LogCache as JSON for the polling function
+ # ----------------------------------------------------------------
"/getLogs" {
if ($request.HttpMethod -eq "GET") {
$jsonLogs = $Global:LogCache | ConvertTo-Json
@@ -1577,31 +1945,34 @@ try {
$response.OutputStream.Close()
}
}
+
"/quit" {
if ($request.HttpMethod -eq "GET") {
$responseString = "Server shutting down."
- $buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
- $response.ContentType = "text/plain"
+ $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()
+ $listener.stop()
break
}
}
+
default {
- $response.StatusCode = 404
+ $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) {
@@ -1617,3 +1988,4 @@ finally {
Write-LogHybrid -Message "Listener object is null; nothing to stop." -Level "Warning"
}
}
+
Steph's Pick
-
-
- Apps
-
-
-
-
-
+
+
+
+
-
+
-
-
+
+
+
-
-
+
- Logs will appear here...
-
-
-
-
-
Logs will appear here...
-