diff --git a/SVSTaskGateold.ps1 b/SVSTaskGateold.ps1 deleted file mode 100644 index 4752279..0000000 --- a/SVSTaskGateold.ps1 +++ /dev/null @@ -1,1991 +0,0 @@ -### 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 - - -# --------------------------------------------------------------------------- -# 1) CREATE A GLOBAL LOG CACHE (NEW) -# --------------------------------------------------------------------------- -# - 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 - ) - - # Simplified Event ID mapping for consistent logging - $EventID = switch ($Level) { - "Info" { 1000 } - "Warning" { 2000 } - "Error" { 3000 } - "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 - } - - # Map levels to colors for console output - $Color = switch ($Level) { - "Info" { "Cyan" } - "Warning" { "Yellow" } - "Error" { "Red" } - "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" } - "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 - } - } - } - - ### Hybrid Function: - # Wrapper for Write-LogHelper to simplify usage across modules. - 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 { - # If Write-Log exists, define Write-LogHybrid to use Write-Log - 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 - } -} - -# 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 - ) - - - # Ensure mandatory parameters are provided - if (-not $ApiUrl -or -not $ApiKey -or -not $ApiSecretKey) { - Write-LogHybrid -Message "Missing required parameters. Please provide ApiUrl, ApiKey, and ApiSecretKey." -Level "Error" -LogToEvent - return - } - - # Enable secure protocols - [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 - - # Step 1: Fetch OAuth token - Write-LogHybrid -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-LogHybrid -Message "OAuth token fetched successfully." -Level "Success" -LogToEvent - } catch { - Write-LogHybrid -Message "Failed to fetch OAuth token. Details: $($_.Exception.Message)" -Level "Error" -LogToEvent - return - } - - # Set headers for the API request - $getHeaders = @{"Authorization" = "Bearer $requestToken"} - - # Step 2: Fetch list of sites - 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 { - [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 - -### 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", - "Install-CyberQP", - "Install-RocketCyber", - "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 "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 - } - } - - # Step 2: Remove all old repositories - 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 - # - 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 - 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 - } - } - - # 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)) { - 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 - } - - # 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 - 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 - } - - ### 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 - - 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 - -# ---------------------------------------------------------------------------------- -# 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 - } - 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 - $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 - - - - # return $data - } - catch { - Write-Host "Error making the GET request:" -ForegroundColor Red - Write-Host $_.Exception.Message - return $null - } -} - - -# Define the HTML Content with an Off-Boarding Tab -function GetHtmlContent { - @" - - - - - - SVS TaskGate - - - - -
- SVS Logo -
-
- -
- -
-

On-Boarding

-

This new deployment method ensures everything is successfully deployed with greater ease!

- -
- -
-

SVSMSP Stack

- - - - - - - - - - -
- - -
-

Optional

- - - -
-
- - -
- -
- - - -
- -
- -
-

Off-Boarding

-
- - - - - - - - - - - -
- -
-
-
-
-

Tweaks

-
- -
-

System Optimizations

-
- - - - -
-
- - -
-

Additional Tweaks

-
- - - -
-
- - -
-

Miscellaneous

-
- - -
-
-
- -
- -
-
- - - -
- -
- - -
-

Logs will appear here...

-
-
- - - -"@ -} - - - -# 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) - $response.ContentType = "text/html" - $response.ContentLength64 = $buffer.Length - $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 - - # 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 - $buffer = [System.Text.Encoding]::UTF8.GetBytes("No sites found") - $response.OutputStream.Write($buffer, 0, $buffer.Length) - $response.OutputStream.Close() - continue - } - - # Return site details as JSON. - $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 { - # 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 - - # 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 - $responseString = "Error: Missing required input parameters." - $buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString) - $response.OutputStream.Write($buffer, 0, $buffer.Length) - $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" - } - if ($checkedValues -contains 'rmm') { - $installRMMCommand += " -InstallRMM" - } - if ($checkedValues -contains 'exe') { - $installRMMCommand += " -SaveCopy" - } - - - - # Step 5: Execute the Command - 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 { - # 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." - $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 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() - } - - - "/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 = " 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 - } - $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() - } - - - "/offboard" { - if ($request.HttpMethod -eq "POST") { - try { - # 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." - $buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString) - $response.OutputStream.Write($buffer, 0, $buffer.Length) - $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 } - "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" - } - } - } - - # 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 - $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 { - # 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 - $responseString = "Error: No tweaks selected." - $buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString) - $response.OutputStream.Write($buffer, 0, $buffer.Length) - $response.OutputStream.Close() - return - } - - # Step 3: Run Selected Tweaks - 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" - #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" - } - } - } - - # 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 - $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() - } - } - - - # ---------------------------------------------------------------- - # 4) NEW ROUTE: /getLogs - # Returns $Global:LogCache as JSON for the polling function - # ---------------------------------------------------------------- - "/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" - } -} -