From 3468cf099194a1826984c63d1b8a58829b7ef386 Mon Sep 17 00:00:00 2001 From: Stephan Yelle Date: Tue, 28 Jan 2025 00:42:33 -0500 Subject: [PATCH] Update SVSTaskGate.ps1 --- SVSTaskGate.ps1 | 331 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 257 insertions(+), 74 deletions(-) diff --git a/SVSTaskGate.ps1 b/SVSTaskGate.ps1 index 24f7714..b378e72 100644 --- a/SVSTaskGate.ps1 +++ b/SVSTaskGate.ps1 @@ -5,22 +5,31 @@ ### 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 -### for the offboarding button, we need to fix the uninstall-svsmsp module ### 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 +### need to have the fetch button check if Install-DattoRMM function exist if not run the build in helpder function to fetch sites +### need to move the tweaks to the tweeks tab + -#region Write-Log # --------------------------------------------------------------------------- # 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 } - -# Check if the Write-Log function exists +#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 { @@ -35,7 +44,7 @@ if (-not (Get-Command -Name Write-Log -CommandType Function -ErrorAction Silentl [int]$CustomEventID # Optional custom Event ID ) - # Simplified Event ID mapping + # Simplified Event ID mapping for consistent logging $EventID = switch ($Level) { "Info" { 1000 } "Warning" { 2000 } @@ -53,7 +62,7 @@ if (-not (Get-Command -Name Write-Log -CommandType Function -ErrorAction Silentl "General" { ([char]0x1F4E6) } # Package icon } - # Map levels to colors + # Map levels to colors for console output $Color = switch ($Level) { "Info" { "Cyan" } "Warning" { "Yellow" } @@ -66,8 +75,9 @@ if (-not (Get-Command -Name Write-Log -CommandType Function -ErrorAction Silentl # Write-Host "$Icon [$Level] [$TaskCategory] $Message (Event ID: $EventID)" -ForegroundColor $Color # ------------------------------------------------------------------- - # 2) ALSO STORE THE LOG IN OUR GLOBAL LOG CACHE (NEW) + # 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 @@ -75,8 +85,11 @@ if (-not (Get-Command -Name Write-Log -CommandType Function -ErrorAction Silentl } [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" - # Optionally log to the Windows Event Log + # Optional: Log to Windows Event Log for system-wide visibility. if ($LogToEvent) { $EntryType = switch ($Level) { "Info" { "Information" } @@ -98,6 +111,8 @@ 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, @@ -136,10 +151,77 @@ else { # 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-Log -Message "Missing required parameters. Please provide ApiUrl, ApiKey, and ApiSecretKey." -Level "Error" -LogToEvent + return + } + + # Enable secure protocols + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + + # Step 1: Fetch OAuth token + Write-Log -Message "Fetching OAuth token..." -Level "Info" + try { + $securePassword = ConvertTo-SecureString -String 'public' -AsPlainText -Force + $apiGenToken = Invoke-WebRequest -Credential (New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList ('public-client', $securePassword)) ` + -Uri ('{0}/auth/oauth/token' -f $ApiUrl) ` + -Method 'POST' ` + -ContentType 'application/x-www-form-urlencoded' ` + -Body ('grant_type=password&username={0}&password={1}' -f $ApiKey, $ApiSecretKey) ` + | ConvertFrom-Json + $requestToken = $apiGenToken.access_token + Write-Log -Message "OAuth token fetched successfully." -Level "Success" -LogToEvent + } catch { + Write-Log -Message "Failed to fetch OAuth token. Details: $($_.Exception.Message)" -Level "Error" -LogToEvent + return + } + + # 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 - - function Install-SVSMSP { param ( # Cleanup flag @@ -197,10 +279,7 @@ function Install-SVSMSP { [Parameter(Mandatory = $false)] [string]$ApiSecretKey ) - - - - + function Perform-Cleanup { Write-LogHybrid -Message "Cleanup mode enabled. Starting cleanup process..." -Level "Info" -LogToEvent @@ -594,6 +673,7 @@ function GetHtmlContent {
+

SVSMSP Stack

-

Tweaks

-
- - - - - +
+ +
+

System Optimizations

+
+ + + + +
+
+ + +
+

Additional Tweaks

+
+ + + +
+
+ + +
+

Miscellaneous

+
+ + +
+
+
- +
+ +
@@ -891,43 +1020,97 @@ function GetHtmlContent { }); } - - function toggleTweaksCheckboxes(selectAllCheckbox) { - // Get all checkboxes inside the tweaksTab container - const checkboxes = document - .getElementById('tweaksTab') - .querySelectorAll('input[type="checkbox"]:not(#selectAllTweaksCheckbox)'); - - // Set the checked state of all checkboxes to match the "Select All" checkbox - checkboxes.forEach(checkbox => { - checkbox.checked = selectAllCheckbox.checked; - }); - } - - function updateSelectAllTweaks() { - const selectAllCheckbox = document.getElementById('selectAllTweaksCheckbox'); - const checkboxes = document - .getElementById('tweaksTab') - .querySelectorAll('input[type="checkbox"]:not(#selectAllTweaksCheckbox)'); - - // If any checkbox is unchecked, uncheck "Select All" - selectAllCheckbox.checked = Array.from(checkboxes).every(checkbox => checkbox.checked); - } - - // Attach the updateSelectAllTweaks function to all individual checkboxes - document.querySelectorAll('#tweaksTab input[type="checkbox"]:not(#selectAllTweaksCheckbox)').forEach(checkbox => { - checkbox.addEventListener('change', updateSelectAllTweaks); - }); - - function triggerTweaks() { - const setedgedefaultsearch = document.querySelector('input[name="setedgedefaultsearch"]'); - - - if (setedgedefaultsearch.checked) { - fetch('/setedgedefaultsearch', { method: 'GET' }) + 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 checkbox = document.getElementById('installDattoRMMCheckbox'); @@ -964,7 +1147,7 @@ function GetHtmlContent { }); // Trigger fetchSites() on Enter key press n8nPasswordInput.addEventListener('keydown', (event) => { - if (event.key === 'Enter' && n8nPasswordInput.value.length >= 4) { + if (event.key === 'Enter' && n8nPasswordInput.value.length >= 12) { fetchSites(); // Call the fetchSites function } }); @@ -1239,7 +1422,7 @@ try { $password = $data.password Get-N8nWebhookData -AuthHeaderValue $password - $sites = Install-DattoRMM -ApiUrl $ApiUrl -ApiKey $ApiKey -ApiSecretKey $ApiSecretKey -FetchSitesOnly + $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 @@ -1580,7 +1763,7 @@ try { # Process each selected task foreach ($task in $selectedTasks) { switch ($task) { - "uninstallSVSMSPModule" { Write-LogHybrid -Message "Uninstalling SVSMSP Module..." -Level "Info"; } #Uninstall-SVSMSP } + "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 }