Update SVSTaskGate.ps1
This commit is contained in:
331
SVSTaskGate.ps1
331
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 {
|
||||
<div class="columns-container">
|
||||
<!-- Left column -->
|
||||
<div class="checkbox-group column" id="leftColumn">
|
||||
<h3 style="font-size: 1.5rem; font-weight: bold;">SVSMSP Stack</h3>
|
||||
<label>
|
||||
<input type="checkbox" id="selectAllLeftCheckbox" onclick="toggleLeftColumnCheckboxes(this)">
|
||||
Select All
|
||||
@@ -650,6 +730,7 @@ function GetHtmlContent {
|
||||
|
||||
<!-- Right column -->
|
||||
<div class="checkbox-group column" id="rightColumn" >
|
||||
<h3 style="font-size: 1.5rem; font-weight: bold;">Optional</h3>
|
||||
<label>
|
||||
<input type="checkbox" class="right-checkbox" name="EnableBitLocker" id="EnableBitLockerCheckbox">
|
||||
Enable Bitlocker
|
||||
@@ -735,35 +816,83 @@ function GetHtmlContent {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- tweaks Tab -->
|
||||
<div id="tweaksTab" class="tab-content inactive">
|
||||
<h2>Tweaks</h2>
|
||||
<div class="checkbox-group">
|
||||
<label>
|
||||
<input type="checkbox" id="selectAllTweaksCheckbox" onclick="toggleTweaksCheckboxes(this)">
|
||||
Select All
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" name="setedgedefaultsearch" id="setedgedefaultsearchCheckbox">
|
||||
Set Edge Default Search Engine
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" name="disableAnimations" id="disableAnimationsCheckbox">
|
||||
Disable Animations
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" name="optimizePerformance" id="optimizePerformanceCheckbox">
|
||||
Optimize Performance
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" name="increaseFontSize" id="increaseFontSizeCheckbox">
|
||||
Increase Font Size
|
||||
</label>
|
||||
<div class="columns-container">
|
||||
<!-- Column 1 -->
|
||||
<div class="column" id="tweaksColumn1">
|
||||
<h3>System Optimizations</h3>
|
||||
<div class="checkbox-group">
|
||||
<label>
|
||||
<input type="checkbox" name="setedgedefaultsearch" id="setedgedefaultsearchCheckbox">
|
||||
Set Edge Default Search Engine
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" name="setWindowsPerformance" id="setWindowsPerformanceCheckbox" onclick="toggleRadioButtons(this)">
|
||||
Optimize Windows Performance
|
||||
</label>
|
||||
<div class="radio-group" id="windowsPerformanceOptions" style="margin-left: 20px; display: none;">
|
||||
<label>
|
||||
<input type="radio" name="optimizeWindowsPerformanceLevel" value="full">
|
||||
Full
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="optimizeWindowsPerformanceLevel" value="partial">
|
||||
Partial
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="optimizeWindowsPerformanceLevel" value="none" checked>
|
||||
None
|
||||
</label>
|
||||
</div>
|
||||
<label>
|
||||
<input type="checkbox" name="stopUnnecessaryServices" id="stopUnnecessaryServicesCheckbox">
|
||||
Stop Unnecessary Services
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Column 2 -->
|
||||
<div class="column" id="tweaksColumn2">
|
||||
<h3>Additional Tweaks</h3>
|
||||
<div class="checkbox-group">
|
||||
<label>
|
||||
<input type="checkbox" name="disableAnimations" id="disableAnimationsCheckbox">
|
||||
Disable Animations
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" name="optimizePerformance" id="optimizePerformanceCheckbox">
|
||||
Optimize Application Performance
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" name="increaseFontSize" id="increaseFontSizeCheckbox">
|
||||
Increase Font Size
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Column 3 -->
|
||||
<div class="column" id="tweaksColumn3">
|
||||
<h3>Miscellaneous</h3>
|
||||
<div class="checkbox-group">
|
||||
<label>
|
||||
<input type="checkbox" name="enableDarkMode" id="enableDarkModeCheckbox">
|
||||
Enable Dark Mode
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" name="clearTempFiles" id="clearTempFilesCheckbox">
|
||||
Clear Temporary Files
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="button-group">
|
||||
<button class="install-button" onclick="triggerTweaks()">Tweaks</button>
|
||||
<button class="install-button" onclick="triggerTweaks()">Apply Tweaks</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Shared Exit Button -->
|
||||
<div class="button-group">
|
||||
<button class="exit-button" onclick="endSession()">Exit</button>
|
||||
@@ -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 }
|
||||
|
||||
Reference in New Issue
Block a user