diff --git a/TGBeta.ps1 b/TGBeta.ps1 index bc32818..52360b8 100644 --- a/TGBeta.ps1 +++ b/TGBeta.ps1 @@ -3,44 +3,31 @@ ### 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 +### for the reg tweak need to do/undo function maybe it should have its own check box list ### added offboard check boxes for dattormm, dattodeb, rocketcyber, cyberQP, SVSHelpdesk and Splashtop ### need to fix path in the uninstall-DattoEDR - ####### ❌ [Error] [GeneralTask] Uninstallation command 'C:\Program Files\Infocyte\Agent\agent.exe' not found. (Event ID: 3000) - bad path - # --------------------------------------------------------------------------- # 1) CREATE A GLOBAL LOG CACHE (NEW) # --------------------------------------------------------------------------- -# - Global log cache stores logs for session-wide accessibility. -# - Logs are stored in a [System.Collections.ArrayList] for easy JSON conversion. -# - Ensure log cache integrity during session restarts. if (-not $Global:LogCache -or -not ($Global:LogCache -is [System.Collections.ArrayList])) { $Global:LogCache = New-Object System.Collections.ArrayList } #region Write-LogHelper -# --------------------------------------------------------------------------- -# 2) DEFINE THE Write-LogHelper FUNCTION -# --------------------------------------------------------------------------- -# - Write-LogHelper manages logging with customizable levels, task categories, and optional event logging. -# - Supported log levels: Info, Warning, Error, Success, General. -# - Task categories should match high-level operations (e.g., "On-boarding", "Off-boarding"). if (-not (Get-Command -Name Write-Log -CommandType Function -ErrorAction SilentlyContinue)) { - # If the Write-Log function doesn't exist, create the Write-LogHelper function function Write-LogHelper { param ( [string]$Message, [ValidateSet("Info", "Warning", "Error", "Success", "General")] [string]$Level = "Info", - [string]$TaskCategory = "GeneralTask", # Task Category for the log entry - [switch]$LogToEvent = $false, # Log to Windows Event Log - [string]$EventSource = "SVSMSP_Module", # Event Source - [string]$EventLog = "Application", # Event Log (default: Application) - [int]$CustomEventID # Optional custom Event ID + [string]$TaskCategory = "GeneralTask", + [switch]$LogToEvent = $false, + [string]$EventSource = "SVSMSP_Module", + [string]$EventLog = "Application", + [int]$CustomEventID ) - - # Simplified Event ID mapping for consistent logging $EventID = switch ($Level) { "Info" { 1000 } "Warning" { 2000 } @@ -48,17 +35,13 @@ if (-not (Get-Command -Name Write-Log -CommandType Function -ErrorAction Silentl "Success" { 4000 } "General" { 1000 } } - - # Icons for each level $Icon = switch ($Level) { - "Info" { [System.Char]::ConvertFromUtf32(0x1F4CB) } # Information icon - "Warning" { ([char]0x26A0) } # Warning icon - "Error" { ([char]0x274C) } # Error icon - "Success" { ([char]0x2705) } # Success icon - "General" { ([char]0x1F4E6) } # Package icon + "Info" { [System.Char]::ConvertFromUtf32(0x1F4CB) } + "Warning" { ([char]0x26A0) } + "Error" { ([char]0x274C) } + "Success" { ([char]0x2705) } + "General" { ([char]0x1F4E6) } } - - # Map levels to colors for console output $Color = switch ($Level) { "Info" { "Cyan" } "Warning" { "Yellow" } @@ -66,26 +49,12 @@ if (-not (Get-Command -Name Write-Log -CommandType Function -ErrorAction Silentl "Success" { "Green" } "General" { "White" } } - - # Write to the PowerShell console - # Write-Host "$Icon [$Level] [$TaskCategory] $Message (Event ID: $EventID)" -ForegroundColor $Color - - # ------------------------------------------------------------------- - # 3) STORE LOGS IN GLOBAL CACHE - # ------------------------------------------------------------------- - # - Cache format: Timestamp, Level, and Message for each log entry. $logEntry = [PSCustomObject]@{ Timestamp = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") Level = $Level Message = "$Icon [$Level] [$TaskCategory] $Message (Event ID: $EventID)" } [void]$Global:LogCache.Add($logEntry) - # ------------------------------------------------------------------- - ### TODO: Add support for exporting logs to a persistent file. - # Consider implementing a periodic export mechanism to save logs to a file. - # Example: Export-LogCacheToFile -Path "C:\Logs\TaskLogs.json" - - # Optional: Log to Windows Event Log for system-wide visibility. if ($LogToEvent) { $EntryType = switch ($Level) { "Info" { "Information" } @@ -93,7 +62,6 @@ if (-not (Get-Command -Name Write-Log -CommandType Function -ErrorAction Silentl "Error" { "Error" } default { "Information" } } - try { if (-not (Get-EventLog -LogName $EventLog -Source $EventSource -ErrorAction SilentlyContinue)) { New-EventLog -LogName $EventLog -Source $EventSource -ErrorAction SilentlyContinue @@ -106,9 +74,6 @@ if (-not (Get-Command -Name Write-Log -CommandType Function -ErrorAction Silentl } } } - - ### Hybrid Function: - # Wrapper for Write-LogHelper to simplify usage across modules. function Write-LogHybrid { param ( [string]$Message, @@ -126,7 +91,6 @@ if (-not (Get-Command -Name Write-Log -CommandType Function -ErrorAction Silentl } } else { - # If Write-Log exists, define Write-LogHybrid to use Write-Log function Write-LogHybrid { param ( [string]$Message, @@ -143,34 +107,24 @@ else { -CustomEventID $CustomEventID } } - -# Example usage of Write-LogHybrid Write-LogHybrid -Message "Starting SVS TaskGate" -Level "Info" -TaskCategory "SVSTaskGate" -LogToEvent:$true #endregion #region Install-DattoRMM-Helper - function Install-DattoRMM-Helper { param ( [string]$ApiUrl, [string]$ApiKey, [string]$ApiSecretKey, - [switch]$FetchSitesOnly, # Fetch client sites without performing installation - [string]$SiteName, # For actual installation, pass the selected site Name - [string]$SiteUID # For actual installation, pass the selected site UID + [switch]$FetchSitesOnly, + [string]$SiteName, + [string]$SiteUID ) - - - # Ensure mandatory parameters are provided if (-not $ApiUrl -or -not $ApiKey -or -not $ApiSecretKey) { Write-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 @@ -186,11 +140,7 @@ function Install-DattoRMM-Helper { 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 { @@ -214,52 +164,74 @@ function Install-DattoRMM-Helper { } #endregion +#region LastPass Extensions +function ForceInstall-LastPassChrome { + # Chrome (Web Store) extension ID and update URL for LastPass + $ExtensionID_LastPass_Chrome = "hdokiejnpimakedhajhdlcegeplioahd" + $ChromeUpdateURL = "https://clients2.google.com/service/update2/crx" + $ChromePolicyRegPath = "HKLM:\SOFTWARE\Policies\Google\Chrome\ExtensionInstallForcelist" + try { + New-Item -Path "HKLM:\SOFTWARE\Policies\Google" -Force -ErrorAction SilentlyContinue | Out-Null + New-Item -Path "HKLM:\SOFTWARE\Policies\Google\Chrome" -Force -ErrorAction SilentlyContinue | Out-Null + New-Item -Path $ChromePolicyRegPath -Force -ErrorAction SilentlyContinue | Out-Null + $chromeValue = "$ExtensionID_LastPass_Chrome;$ChromeUpdateURL" + Set-ItemProperty -Path $ChromePolicyRegPath -Name "1" -Value $chromeValue -ErrorAction Stop + Write-Host "Successfully configured LastPass in Chrome ExtensionInstallForcelist." + } + catch { + Write-Host "Failed to configure Chrome: $($_.Exception.Message)" -ForegroundColor Red + } +} +function ForceInstall-LastPassEdge { + # Edge (Add-ons Store) extension ID and update URL for LastPass + $ExtensionID_LastPass_Edge = "bbcinlkgjjkejfdpemiealijmmooekmp" + $EdgeUpdateURL = "https://edge.microsoft.com/extensionwebstorebase/v1/crx" + $EdgePolicyRegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Edge\ExtensionInstallForcelist" + try { + New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft" -Force -ErrorAction SilentlyContinue | Out-Null + New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Edge" -Force -ErrorAction SilentlyContinue | Out-Null + New-Item -Path $EdgePolicyRegPath -Force -ErrorAction SilentlyContinue | Out-Null + $edgeValue = "$ExtensionID_LastPass_Edge;$EdgeUpdateURL" + Set-ItemProperty -Path $EdgePolicyRegPath -Name "1" -Value $edgeValue -ErrorAction Stop + Write-Host "Successfully configured LastPass in Edge ExtensionInstallForcelist." + } + catch { + Write-Host "Failed to configure Edge: $($_.Exception.Message)" -ForegroundColor Red + } +} + +function Install-LastPassExtensions { + param( + [switch]$Chrome, + [switch]$Edge + ) + if ($Chrome) { ForceInstall-LastPassChrome } + if ($Edge) { ForceInstall-LastPassEdge } +} +#endregion #region SVS Module - -### SVS Module Overview: -# - This section includes the Install-SVSMSP function, which handles: -# 1. Cleanup of old modules and repositories. -# 2. Installation of new modules and repositories. -# 3. Setting execution policies and prerequisites. -# - TODO: -# 1. Validate all parameters for completeness and add error messages for missing inputs. -# 2. Refactor cleanup and installation steps for modularity and reusability. - - function Install-SVSMSP { param ( - # Cleanup flag: Removes old modules and repositories if enabled. [switch]$Cleanup, - - # Toolkit installation flag: Installs required modules and repositories. [switch]$InstallToolkit, - - # Module settings [Parameter(Mandatory = $false)] [array]$AllModules = @( @{ ModuleName = "SVS_Toolkit" }, @{ ModuleName = "SVSMSP" } ), - [Parameter(Mandatory = $false)] [string]$NewModuleName = "SVSMSP", - - # Repository settings [Parameter(Mandatory = $false)] [array]$AllRepositories = @( @{ RepoName = "SVS_Repo" }, @{ RepoName = "SVS_Toolkit" } ), - [Parameter(Mandatory = $false)] [string]$NewRepositoryName = "SVS_Repo", - [Parameter(Mandatory = $false)] [string]$NewRepositoryURL = "http://proget.svstools.ca:8083/nuget/SVS_Repo/", - - # Commands to check [Parameter(Mandatory = $false)] [array]$CommandsToCheck = @( "Install-DattoRMM", @@ -268,22 +240,12 @@ function Install-SVSMSP { "Install-Splashtop", "Install-ThreatLocker", "Install-SVSHelpdesk" - ), - - # Log file path for tracking installation steps [Parameter(Mandatory = $false)] [string]$LogFilePath = "$env:SVSMSP\svstoolkit.log" - ) - - ### Function: Perform-Cleanup - # - Removes all old modules and repositories. - # - Logs each step for debugging purposes. function Perform-Cleanup { Write-LogHybrid -Message "Cleanup mode enabled. Starting cleanup process..." -Level "Info" -LogToEvent - - # Step 1: Remove all old modules Write-LogHybrid -Message "Starting cleanup of old modules..." -Level "Info" -LogToEvent foreach ($module in $AllModules) { $ModuleName = $module.ModuleName @@ -303,8 +265,6 @@ function Install-SVSMSP { Write-LogHybrid -Message "Module '$ModuleName' not found. Skipping..." -Level "Info" -LogToEvent } } - - # Step 2: Remove all old repositories Write-LogHybrid -Message "Starting cleanup of old repositories..." -Level "Info" -LogToEvent foreach ($repo in $AllRepositories) { $RepoName = $repo.RepoName @@ -322,19 +282,10 @@ function Install-SVSMSP { Write-LogHybrid -Message "Repository '$RepoName' does not exist. Skipping removal." -Level "Info" -LogToEvent } } - Write-LogHybrid -Message "Cleanup process completed successfully." -Level "Success" -LogToEvent } - - ### 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 @@ -347,11 +298,7 @@ function Install-SVSMSP { return } } - - # Step 3: Ensure NuGet is Installed Install-PackageProvider -Name "NuGet" -Force -Scope AllUsers -Confirm:$false - - # Step 4: Register the new repository Write-LogHybrid -Message "Registering the new repository '$NewRepositoryName'..." -Level "Info" -LogToEvent try { if (!(Get-PSRepository -Name $NewRepositoryName -ErrorAction SilentlyContinue)) { @@ -362,8 +309,6 @@ function Install-SVSMSP { catch { Write-LogHybrid -Message "Failed to register new repository '$NewRepositoryName'. Error: $($_.Exception.Message)" -Level "Error" -LogToEvent } - - # Step 5: Install the new module Write-LogHybrid -Message "Installing the new module '$NewModuleName'..." -Level "Info" -LogToEvent try { Install-Module -Name $NewModuleName -Repository $NewRepositoryName -Scope AllUsers -Force @@ -372,71 +317,43 @@ function Install-SVSMSP { catch { Write-LogHybrid -Message "Failed to install new module '$NewModuleName'. Error: $($_.Exception.Message)" -Level "Error" -LogToEvent } - Write-LogHybrid -Message "Toolkit installation process completed successfully." -Level "Success" -LogToEvent } - - ### 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 +#region HTTP Listener Setup 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 $_ } - - +#endregion function Get-N8nWebhookData { param ( [Parameter(Mandatory = $true)] [string]$AuthHeaderValue ) - $url = "https://automate.svstools.ca/webhook/svsmspkit" $headers = @{ "SVSMSPKit" = $AuthHeaderValue @@ -444,10 +361,7 @@ function Get-N8nWebhookData { try { $response = Invoke-RestMethod -Uri $url -Headers $headers -Method Get Write-Host "Response received successfully:" -ForegroundColor Green - $data = $response - - # Map fields $global:Comment_SVSmodule = $data._Comment_SVSmodule $global:ModuleName = $data.ModuleName $global:RepositoryURL = $data.RepositoryURL @@ -459,10 +373,6 @@ function Get-N8nWebhookData { $global:ApiUrl = $data.ApiUrl $global:ApiKey = $data.ApiKey $global:ApiSecretKey = $data.ApiSecretKey - - - - # return $data } catch { Write-Host "Error making the GET request:" -ForegroundColor Red @@ -471,10 +381,9 @@ function Get-N8nWebhookData { } } - -# Define the HTML Content with an Off-Boarding Tab +#region HTML Content function GetHtmlContent { - @" + @" @@ -484,69 +393,65 @@ function GetHtmlContent { @@ -687,15 +591,14 @@ function GetHtmlContent { +

On-Boarding

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

-
-

SVSMSP Stack

- -

Optional

-
-
- + -
-

Off-Boarding

-
+
+
+
+
+

Tweaks

-

System Optimizations

@@ -875,8 +771,6 @@ function GetHtmlContent {
- -

Additional Tweaks

@@ -894,8 +788,6 @@ function GetHtmlContent {
- -

Miscellaneous

@@ -910,37 +802,111 @@ function GetHtmlContent {
-
- - + +
+

SVS APPs

+ +
+

Winget Apps

+ + + + + + + + + + +
+ +
+

Extensions

+ + +
+
+ + +
+
-

Logs will appear here...

+
+ } + setInterval(fetchLogs, 3000); + + "@ } - - - # Save and launch the HTML Start-Process "msedge.exe" -ArgumentList "--app=http://localhost:8081/" - +#region HTTP Listener Route Handling 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) @@ -1527,24 +1418,15 @@ 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 - - # 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 @@ -1553,15 +1435,13 @@ 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" $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.") @@ -1570,7 +1450,6 @@ try { } } } - "/installSVSMSPModule" { if ($request.HttpMethod -eq "GET") { try { @@ -1590,23 +1469,16 @@ try { $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 @@ -1616,10 +1488,7 @@ 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" } @@ -1629,10 +1498,6 @@ try { if ($checkedValues -contains 'exe') { $installRMMCommand += " -SaveCopy" } - - - - # Step 5: Execute the Command try { Invoke-Expression $installRMMCommand $responseString = "RMM installation triggered successfully for $Name." @@ -1644,35 +1509,26 @@ 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 + $responseString = "Method not allowed. Use POST." $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." @@ -1691,8 +1547,6 @@ try { $response.OutputStream.Write($buffer, 0, $buffer.Length) $response.OutputStream.Close() } - - "/installCyberQP" { if ($request.HttpMethod -eq "GET") { try { @@ -1712,9 +1566,7 @@ try { $response.ContentLength64 = $buffer.Length $response.OutputStream.Write($buffer, 0, $buffer.Length) $response.OutputStream.Close() - } - "/installSplashtop" { if ($request.HttpMethod -eq "GET") { try { @@ -1735,153 +1587,94 @@ try { $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 + 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 + 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 - } + 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 = " 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 + 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." @@ -1890,8 +1683,6 @@ 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 } @@ -1908,16 +1699,12 @@ try { } } } - - # 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 @@ -1931,17 +1718,12 @@ try { $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 @@ -1951,8 +1733,6 @@ try { $response.OutputStream.Close() return } - - # Step 3: Run Selected Tweaks foreach ($tweak in $tweaks) { switch ($tweak) { "enableDarkModeCheckbox" { @@ -1961,31 +1741,24 @@ 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" } } } - - # 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 @@ -1999,12 +1772,6 @@ 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 @@ -2015,7 +1782,34 @@ try { $response.OutputStream.Close() } } - + # New route for installing LastPass Extensions + "/installExtensions" { + if ($request.HttpMethod -eq "POST") { + try { + $bodyStream = New-Object IO.StreamReader $request.InputStream + $body = $bodyStream.ReadToEnd() | Out-String + $data = ConvertFrom-Json $body + $installChrome = $data.chrome + $installEdge = $data.edge + Install-LastPassExtensions -Chrome:$installChrome -Edge:$installEdge + $responseString = "LastPass extensions installation triggered." + $response.StatusCode = 200 + } + catch { + $responseString = "Error processing extensions 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() + } "/quit" { if ($request.HttpMethod -eq "GET") { $responseString = "Server shutting down." @@ -2029,7 +1823,6 @@ try { break } } - default { $response.StatusCode = 404 $response.StatusDescription = "Not Found" @@ -2042,7 +1835,6 @@ try { } catch { Write-Host "Error: $($_.Exception.Message)" - } finally { if ($listener -ne $null) { @@ -2058,4 +1850,3 @@ finally { Write-LogHybrid -Message "Listener object is null; nothing to stop." -Level "Warning" } } -