Update SVSTaskGate.ps1
This commit is contained in:
363
SVSTaskGate.ps1
363
SVSTaskGate.ps1
@@ -1,84 +1,92 @@
|
|||||||
### now that we have a field for user to enter N8N password we need to figure out how we can make the fetch site button refresh the downdown after
|
|
||||||
### add tweek to set default provider, add to toolkit?
|
### add tweek to set default provider, add to toolkit?
|
||||||
### power settings in tweeks or onboarding?
|
### power settings in tweeks or onboarding?
|
||||||
### make script install the toolkit
|
|
||||||
### test the write-log in the log box and in the event viewer
|
|
||||||
### need to see if there's anything else we could take from Theo script?
|
### need to see if there's anything else we could take from Theo script?
|
||||||
### make when using select all the datto rmm pus var runs before install-splashtop
|
### make when using select all the datto rmm pus var runs before install-splashtop
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# 1) CREATE A GLOBAL LOG CACHE (NEW)
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
$Global:LogCache = New-Object System.Collections.ArrayList
|
||||||
|
|
||||||
|
|
||||||
# Check if the Write-Log function exists
|
# Check if the Write-Log function exists
|
||||||
if (-not (Get-Command -Name Write-Log -CommandType Function -ErrorAction SilentlyContinue)) {
|
if (-not (Get-Command -Name Write-Log -CommandType Function -ErrorAction SilentlyContinue)) {
|
||||||
# If the Write-Log function doesn't exist, create the Write-LogHelper function
|
# If the Write-Log function doesn't exist, create the Write-LogHelper function
|
||||||
function Write-LogHelper {
|
function Write-LogHelper {
|
||||||
param (
|
param (
|
||||||
[string]$Message,
|
[string]$Message,
|
||||||
[ValidateSet("Info", "Warning", "Error", "Success", "General")]
|
[ValidateSet("Info", "Warning", "Error", "Success", "General")]
|
||||||
[string]$Level = "Info",
|
[string]$Level = "Info",
|
||||||
[string]$TaskCategory = "GeneralTask", # Task Category for the log entry
|
[string]$TaskCategory = "GeneralTask", # Task Category for the log entry
|
||||||
[switch]$LogToEvent = $false, # Log to Windows Event Log
|
[switch]$LogToEvent = $false, # Log to Windows Event Log
|
||||||
[string]$EventSource = "SVSMSP_Module", # Event Source
|
[string]$EventSource = "SVSMSP_Module", # Event Source
|
||||||
[string]$EventLog = "Application", # Event Log (default: Application)
|
[string]$EventLog = "Application", # Event Log (default: Application)
|
||||||
[int]$CustomEventID # Optional custom Event ID
|
[int]$CustomEventID # Optional custom Event ID
|
||||||
)
|
)
|
||||||
|
|
||||||
# Simplified Event ID mapping
|
# Simplified Event ID mapping
|
||||||
$EventID = switch ($Level) {
|
$EventID = switch ($Level) {
|
||||||
"Info" { 1000 }
|
"Info" { 1000 }
|
||||||
"Warning" { 2000 }
|
"Warning" { 2000 }
|
||||||
"Error" { 3000 }
|
"Error" { 3000 }
|
||||||
"Success" { 4000 }
|
"Success" { 4000 }
|
||||||
"General" { 1000 }
|
"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 for generic tasks/operations
|
|
||||||
}
|
|
||||||
|
|
||||||
# Map levels to colors
|
|
||||||
$Color = switch ($Level) {
|
|
||||||
"Info" { "Cyan" }
|
|
||||||
"Warning" { "Yellow" }
|
|
||||||
"Error" { "Red" }
|
|
||||||
"Success" { "Green" }
|
|
||||||
"General" { "White" }
|
|
||||||
}
|
|
||||||
|
|
||||||
# Include Task Category, Icon, and Message in the console output
|
|
||||||
Write-Host "$Icon [$Level] [$TaskCategory] $Message (Event ID: $EventID)" -ForegroundColor $Color
|
|
||||||
|
|
||||||
# Optionally log to the Windows Event Log
|
|
||||||
if ($LogToEvent) {
|
|
||||||
$EntryType = switch ($Level) {
|
|
||||||
"Info" { "Information" }
|
|
||||||
"Warning" { "Warning" }
|
|
||||||
"Error" { "Error" }
|
|
||||||
default { "Information" }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
# Icons for each level
|
||||||
# Check if the event source exists, create it if necessary
|
$Icon = switch ($Level) {
|
||||||
if (-not (Get-EventLog -LogName $EventLog -Source $EventSource -ErrorAction SilentlyContinue)) {
|
"Info" { [System.Char]::ConvertFromUtf32(0x1F4CB) } # Information icon
|
||||||
New-EventLog -LogName $EventLog -Source $EventSource -ErrorAction SilentlyContinue
|
"Warning" { ([char]0x26A0) } # Warning icon
|
||||||
|
"Error" { ([char]0x274C) } # Error icon
|
||||||
|
"Success" { ([char]0x2705) } # Success icon
|
||||||
|
"General" { ([char]0x1F4E6) } # Package icon
|
||||||
|
}
|
||||||
|
|
||||||
|
# Map levels to colors
|
||||||
|
$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
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------
|
||||||
|
# 2) ALSO STORE THE LOG IN OUR GLOBAL LOG CACHE (NEW)
|
||||||
|
# -------------------------------------------------------------------
|
||||||
|
$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)
|
||||||
|
# -------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Optionally log to the Windows Event Log
|
||||||
|
if ($LogToEvent) {
|
||||||
|
$EntryType = switch ($Level) {
|
||||||
|
"Info" { "Information" }
|
||||||
|
"Warning" { "Warning" }
|
||||||
|
"Error" { "Error" }
|
||||||
|
default { "Information" }
|
||||||
}
|
}
|
||||||
|
|
||||||
# Include Task Category in the Event Log Message
|
try {
|
||||||
$EventMessage = "TaskCategory: $TaskCategory | Message: $Message"
|
if (-not (Get-EventLog -LogName $EventLog -Source $EventSource -ErrorAction SilentlyContinue)) {
|
||||||
|
New-EventLog -LogName $EventLog -Source $EventSource -ErrorAction SilentlyContinue
|
||||||
# Write the event log
|
}
|
||||||
Write-EventLog -LogName $EventLog -Source $EventSource -EntryType $EntryType -EventId $EventID -Message $EventMessage
|
$EventMessage = "TaskCategory: $TaskCategory | Message: $Message"
|
||||||
} catch {
|
Write-EventLog -LogName $EventLog -Source $EventSource -EntryType $EntryType -EventId $EventID -Message $EventMessage
|
||||||
Write-Host "([char]0x26A0) [Warning] [EventLog] Failed to write to Event Log: $($_.Exception.Message)" -ForegroundColor Yellow
|
}
|
||||||
|
catch {
|
||||||
|
Write-Host "([char]0x26A0) [Warning] [EventLog] Failed to write to Event Log: $($_.Exception.Message)" -ForegroundColor Yellow
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
# Define a fallback Write-LogHybrid function that uses Write-LogHelper
|
|
||||||
function Write-LogHybrid {
|
function Write-LogHybrid {
|
||||||
param (
|
param (
|
||||||
[string]$Message,
|
[string]$Message,
|
||||||
@@ -90,8 +98,6 @@ if (-not (Get-Command -Name Write-Log -CommandType Function -ErrorAction Silentl
|
|||||||
[string]$EventLog = "Application",
|
[string]$EventLog = "Application",
|
||||||
[int]$CustomEventID
|
[int]$CustomEventID
|
||||||
)
|
)
|
||||||
|
|
||||||
# Use the helper function to log
|
|
||||||
Write-LogHelper -Message $Message -Level $Level -TaskCategory $TaskCategory `
|
Write-LogHelper -Message $Message -Level $Level -TaskCategory $TaskCategory `
|
||||||
-LogToEvent:$LogToEvent -EventSource $EventSource -EventLog $EventLog `
|
-LogToEvent:$LogToEvent -EventSource $EventSource -EventLog $EventLog `
|
||||||
-CustomEventID $CustomEventID
|
-CustomEventID $CustomEventID
|
||||||
@@ -110,8 +116,6 @@ else {
|
|||||||
[string]$EventLog = "Application",
|
[string]$EventLog = "Application",
|
||||||
[int]$CustomEventID
|
[int]$CustomEventID
|
||||||
)
|
)
|
||||||
|
|
||||||
# Use the existing Write-Log function
|
|
||||||
Write-Log -Message $Message -Level $Level -TaskCategory $TaskCategory `
|
Write-Log -Message $Message -Level $Level -TaskCategory $TaskCategory `
|
||||||
-LogToEvent:$LogToEvent -EventSource $EventSource -EventLog $EventLog `
|
-LogToEvent:$LogToEvent -EventSource $EventSource -EventLog $EventLog `
|
||||||
-CustomEventID $CustomEventID
|
-CustomEventID $CustomEventID
|
||||||
@@ -120,6 +124,7 @@ else {
|
|||||||
|
|
||||||
# Example usage of Write-LogHybrid
|
# Example usage of Write-LogHybrid
|
||||||
Write-LogHybrid -Message "This is a test log message. Write-log2 does exist" -Level "Info" -TaskCategory "TestCategory" -LogToEvent:$true
|
Write-LogHybrid -Message "This is a test log message. Write-log2 does exist" -Level "Info" -TaskCategory "TestCategory" -LogToEvent:$true
|
||||||
|
Write-Log -Message "This is a test log message. Write-log4444 does exist" -Level "Info" -TaskCategory "TestCategory" -LogToEvent:$true
|
||||||
|
|
||||||
|
|
||||||
function Install-SVSMSP {
|
function Install-SVSMSP {
|
||||||
@@ -178,7 +183,6 @@ function Install-SVSMSP {
|
|||||||
[string]$ApiSecretKey = "YOUR_API_SECRET_HERE"
|
[string]$ApiSecretKey = "YOUR_API_SECRET_HERE"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Helper function: Perform Cleanup
|
|
||||||
function Perform-Cleanup {
|
function Perform-Cleanup {
|
||||||
Write-LogHybrid -Message "Cleanup mode enabled. Starting cleanup process..." -Level "Info" -LogToEvent -EventID 1502
|
Write-LogHybrid -Message "Cleanup mode enabled. Starting cleanup process..." -Level "Info" -LogToEvent -EventID 1502
|
||||||
|
|
||||||
@@ -225,9 +229,8 @@ function Install-SVSMSP {
|
|||||||
Write-LogHybrid -Message "Cleanup process completed successfully." -Level "Success" -LogToEvent -EventID 1510
|
Write-LogHybrid -Message "Cleanup process completed successfully." -Level "Success" -LogToEvent -EventID 1510
|
||||||
}
|
}
|
||||||
|
|
||||||
# Helper function: Perform Toolkit Installation
|
|
||||||
function Perform-ToolkitInstallation {
|
function Perform-ToolkitInstallation {
|
||||||
# Perform cleanup to remove old modules and repositories
|
# Perform cleanup
|
||||||
Perform-Cleanup
|
Perform-Cleanup
|
||||||
|
|
||||||
# Step 1: Set Execution Policy
|
# Step 1: Set Execution Policy
|
||||||
@@ -282,7 +285,6 @@ function Install-SVSMSP {
|
|||||||
Write-LogHybrid -Message "Toolkit installation process completed successfully." -Level "Success" -LogToEvent -EventID 1510
|
Write-LogHybrid -Message "Toolkit installation process completed successfully." -Level "Success" -LogToEvent -EventID 1510
|
||||||
}
|
}
|
||||||
|
|
||||||
# Main Logic
|
|
||||||
Write-LogHybrid -Message "Install-SVSMSP function started." -Level "Info" -LogToEvent -EventID 1500
|
Write-LogHybrid -Message "Install-SVSMSP function started." -Level "Info" -LogToEvent -EventID 1500
|
||||||
|
|
||||||
if ($Cleanup) {
|
if ($Cleanup) {
|
||||||
@@ -299,7 +301,7 @@ function Install-SVSMSP {
|
|||||||
Perform-ToolkitInstallation
|
Perform-ToolkitInstallation
|
||||||
}
|
}
|
||||||
|
|
||||||
#Install-SVSMSP -InstallToolkit
|
Install-SVSMSP -InstallToolkit
|
||||||
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------
|
||||||
@@ -316,21 +318,17 @@ function Get-N8nWebhookData {
|
|||||||
[string]$AuthHeaderValue
|
[string]$AuthHeaderValue
|
||||||
)
|
)
|
||||||
|
|
||||||
# Define the URL and headers
|
|
||||||
$url = "https://automate.svstools.ca/webhook/svsmspkit"
|
$url = "https://automate.svstools.ca/webhook/svsmspkit"
|
||||||
$headers = @{
|
$headers = @{
|
||||||
"SVSMSPKit" = $AuthHeaderValue
|
"SVSMSPKit" = $AuthHeaderValue
|
||||||
}
|
}
|
||||||
|
|
||||||
# Make the GET request to the N8N webhook
|
|
||||||
try {
|
try {
|
||||||
$response = Invoke-RestMethod -Uri $url -Headers $headers -Method Get
|
$response = Invoke-RestMethod -Uri $url -Headers $headers -Method Get
|
||||||
Write-Host "Response received successfully:" -ForegroundColor Green
|
Write-Host "Response received successfully:" -ForegroundColor Green
|
||||||
|
|
||||||
# Convert the JSON response to a PowerShell object
|
|
||||||
$data = $response
|
$data = $response
|
||||||
|
|
||||||
# Map each field to a variable (if needed)
|
# Map fields
|
||||||
$global:Comment_SVSmodule = $data._Comment_SVSmodule
|
$global:Comment_SVSmodule = $data._Comment_SVSmodule
|
||||||
$global:ModuleName = $data.ModuleName
|
$global:ModuleName = $data.ModuleName
|
||||||
$global:RepositoryURL = $data.RepositoryURL
|
$global:RepositoryURL = $data.RepositoryURL
|
||||||
@@ -343,18 +341,8 @@ function Get-N8nWebhookData {
|
|||||||
$global:ApiKey = $data.ApiKey
|
$global:ApiKey = $data.ApiKey
|
||||||
$global:ApiSecretKey = $data.ApiSecretKey
|
$global:ApiSecretKey = $data.ApiSecretKey
|
||||||
|
|
||||||
# Print the values
|
|
||||||
Write-Output "Module Name: $ModuleName"
|
|
||||||
Write-Output "Repository URL: $RepositoryURL"
|
|
||||||
Write-Output "Old Repo: $OldRepo"
|
|
||||||
Write-Output "New Repo: $NewRepo"
|
|
||||||
Write-Output "Commands To Check: $($CommandsToCheck -join ', ')"
|
|
||||||
Write-Output "Log File Path: $LogFilePath"
|
|
||||||
Write-Output "API URL: $ApiUrl"
|
|
||||||
Write-Output "API Key: $ApiKey"
|
|
||||||
Write-Output "API Secret Key: $ApiSecretKey"
|
|
||||||
|
|
||||||
# Return the parsed data object
|
|
||||||
return $data
|
return $data
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
@@ -370,11 +358,11 @@ function GetHtmlContent {
|
|||||||
@"
|
@"
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>On-Boarding & Off-Boarding</title>
|
<title>SVS TaskGate</title>
|
||||||
|
<link rel="icon" href="https://git.svstools.com/syelle/Logo/raw/branch/main/SVS_Favicon.ico" type="image/x-icon">
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
font-family: Arial, sans-serif;
|
font-family: Arial, sans-serif;
|
||||||
@@ -383,18 +371,24 @@ function GetHtmlContent {
|
|||||||
background-color: #1e1e1e;
|
background-color: #1e1e1e;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
|
.logo-container {
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #1e1e1e; /* Matches the background color */
|
||||||
|
}
|
||||||
|
.logo-container img {
|
||||||
|
max-width: 300px; /* Adjust size as needed */
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
.container {
|
.container {
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar {
|
.sidebar {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
background-color: #2e2e2e;
|
background-color: #1e1e1e;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar button {
|
.sidebar button {
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -408,30 +402,24 @@ function GetHtmlContent {
|
|||||||
text-align: left;
|
text-align: left;
|
||||||
transition: background-color 0.3s ease, transform 0.2s ease;
|
transition: background-color 0.3s ease, transform 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar button.active {
|
.sidebar button.active {
|
||||||
background-color: #007bff;
|
background-color: #007bff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar button:hover {
|
.sidebar button:hover {
|
||||||
background-color: #0056b3;
|
background-color: #0056b3;
|
||||||
transform: scale(1.05);
|
transform: scale(1.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-content {
|
.tab-content {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-content.active {
|
.tab-content.active {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkbox-group label {
|
.checkbox-group label {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@@ -439,7 +427,6 @@ function GetHtmlContent {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.password-input,
|
.password-input,
|
||||||
.dropdown {
|
.dropdown {
|
||||||
width: 30%;
|
width: 30%;
|
||||||
@@ -450,12 +437,10 @@ function GetHtmlContent {
|
|||||||
background-color: #2e2e2e;
|
background-color: #2e2e2e;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-group {
|
.button-group {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-group button {
|
.button-group button {
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
@@ -463,24 +448,20 @@ function GetHtmlContent {
|
|||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.install-button {
|
.install-button {
|
||||||
background-color: #28a745;
|
background-color: #28a745;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.install-button:disabled {
|
.install-button:disabled {
|
||||||
background-color: #6c757d;
|
background-color: #6c757d;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
.exit-button {
|
.exit-button {
|
||||||
background-color: #dc3545;
|
background-color: #dc3545;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.log {
|
.log {
|
||||||
width: 50%;
|
width: 80%;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
background-color: #333;
|
background-color: #333;
|
||||||
@@ -489,20 +470,20 @@ function GetHtmlContent {
|
|||||||
max-height: 300px;
|
max-height: 300px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.container {
|
.container {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar {
|
.sidebar {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
<div class="logo-container">
|
||||||
|
<img src="https://git.svstools.com/syelle/Logo/raw/branch/main/SVS_Logo.png" alt="SVS Logo">
|
||||||
|
</div>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="sidebar">
|
<div class="sidebar">
|
||||||
<button class="tab-button active" data-tab="onboardTab" aria-expanded="true">On-Boarding</button>
|
<button class="tab-button active" data-tab="onboardTab" aria-expanded="true">On-Boarding</button>
|
||||||
@@ -560,25 +541,21 @@ function GetHtmlContent {
|
|||||||
<input type="checkbox" name="dattoRMMOption" value="exe">
|
<input type="checkbox" name="dattoRMMOption" value="exe">
|
||||||
Download.exe
|
Download.exe
|
||||||
</label>
|
</label>
|
||||||
<br>
|
<br><br>
|
||||||
<br>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="n8nPasswordContainer" style="display: none;">
|
<div id="n8nPasswordContainer" style="display: none;">
|
||||||
<label for="n8nPassword">Enter n8n Password:</label>
|
<label for="n8nPassword">Enter n8n Password:</label><br>
|
||||||
<br>
|
|
||||||
<input type="password" id="n8nPassword" class="password-input" placeholder="Enter N8N Password">
|
<input type="password" id="n8nPassword" class="password-input" placeholder="Enter N8N Password">
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
<div id="DattoRMMContainer" style="display: none;">
|
<div id="DattoRMMContainer" style="display: none;">
|
||||||
<label for="dattoRmmDropdown">Select a Datto RMM site:</label>
|
<label for="dattoRmmDropdown">Select a Datto RMM site:</label><br>
|
||||||
<br>
|
|
||||||
<select id="dattoRmmDropdown" class="dropdown">
|
<select id="dattoRmmDropdown" class="dropdown">
|
||||||
<option value="">Fetching sites...</option>
|
<option value="">Fetching sites...</option>
|
||||||
$siteOptions
|
$siteOptions
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="button-group">
|
<div class="button-group">
|
||||||
<button class="install-button" id="fetchSitesButton" onclick="fetchSites()" disabled>Fetch
|
<button class="install-button" id="fetchSitesButton" onclick="fetchSites()" disabled>Fetch
|
||||||
Sites</button>
|
Sites</button>
|
||||||
@@ -591,6 +568,7 @@ function GetHtmlContent {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function toggleOnboardCheckboxes(selectedCheckbox) {
|
function toggleOnboardCheckboxes(selectedCheckbox) {
|
||||||
const checkboxes = document.querySelectorAll('#onboardTab input[type="checkbox"]');
|
const checkboxes = document.querySelectorAll('#onboardTab input[type="checkbox"]');
|
||||||
@@ -605,7 +583,6 @@ function GetHtmlContent {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Check if "Select All" is checked and handle the Datto RMM-specific logic
|
|
||||||
if (dattoRMMCheckbox.checked) {
|
if (dattoRMMCheckbox.checked) {
|
||||||
optionsContainer.style.display = 'block';
|
optionsContainer.style.display = 'block';
|
||||||
n8nPasswordContainer.style.display = 'block';
|
n8nPasswordContainer.style.display = 'block';
|
||||||
@@ -621,16 +598,11 @@ function GetHtmlContent {
|
|||||||
const checkbox = document.getElementById('installDattoRMMCheckbox');
|
const checkbox = document.getElementById('installDattoRMMCheckbox');
|
||||||
const optionsContainer = document.getElementById('dattoRMMOptionsContainer');
|
const optionsContainer = document.getElementById('dattoRMMOptionsContainer');
|
||||||
const n8nPasswordContainer = document.getElementById('n8nPasswordContainer');
|
const n8nPasswordContainer = document.getElementById('n8nPasswordContainer');
|
||||||
const DattoRMMContainer = document.getElementById('DattoRMMContainer')
|
const DattoRMMContainer = document.getElementById('DattoRMMContainer');
|
||||||
|
|
||||||
// Show or hide the Datto RMM options
|
|
||||||
optionsContainer.style.display = checkbox.checked ? 'block' : 'none';
|
optionsContainer.style.display = checkbox.checked ? 'block' : 'none';
|
||||||
|
|
||||||
// Show or hide the password field
|
|
||||||
n8nPasswordContainer.style.display = checkbox.checked ? 'block' : 'none';
|
n8nPasswordContainer.style.display = checkbox.checked ? 'block' : 'none';
|
||||||
|
DattoRMMContainer.style.display = checkbox.checked ? 'block' : 'none';
|
||||||
// Show or Hide the DattoRMM site list
|
|
||||||
DattoRMMContainer.style.display = checkbox.checked ? 'block' : 'none'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const tabButtons = document.querySelectorAll('.tab-button');
|
const tabButtons = document.querySelectorAll('.tab-button');
|
||||||
@@ -668,7 +640,6 @@ function GetHtmlContent {
|
|||||||
try {
|
try {
|
||||||
appendLog("Fetching sites...", "yellow");
|
appendLog("Fetching sites...", "yellow");
|
||||||
|
|
||||||
// Example fetch request (update URL and payload as needed)
|
|
||||||
const response = await fetch('/getn8npw', {
|
const response = await fetch('/getn8npw', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
@@ -679,24 +650,20 @@ function GetHtmlContent {
|
|||||||
throw new Error('Failed to fetch sites. Please try again.');
|
throw new Error('Failed to fetch sites. Please try again.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the JSON response into an array (or object)
|
|
||||||
const sites = await response.json();
|
const sites = await response.json();
|
||||||
|
|
||||||
// Clear out existing options in the dropdown
|
|
||||||
dropdown.innerHTML = '';
|
dropdown.innerHTML = '';
|
||||||
|
|
||||||
// Populate dropdown with new options
|
|
||||||
sites.forEach(site => {
|
sites.forEach(site => {
|
||||||
const option = document.createElement('option');
|
const option = document.createElement('option');
|
||||||
option.value = site.UID; // or whatever property holds the site ID
|
// Adjust property names based on your actual data
|
||||||
option.textContent = site.Name; // or the relevant display name
|
option.value = site.UID;
|
||||||
|
option.textContent = site.Name;
|
||||||
dropdown.appendChild(option);
|
dropdown.appendChild(option);
|
||||||
});
|
});
|
||||||
|
|
||||||
appendLog("Sites fetched successfully, please select a site!", "green");
|
appendLog("Sites fetched successfully, please select a site!", "green");
|
||||||
|
}
|
||||||
} catch (error) {
|
catch (error) {
|
||||||
// Handle errors and display a fallback option
|
|
||||||
dropdown.innerHTML = '<option value="">Fetching sites failed</option>';
|
dropdown.innerHTML = '<option value="">Fetching sites failed</option>';
|
||||||
appendLog('Error:' + error.message, "red");
|
appendLog('Error:' + error.message, "red");
|
||||||
}
|
}
|
||||||
@@ -707,7 +674,7 @@ function GetHtmlContent {
|
|||||||
const UID = dropdown.options[dropdown.selectedIndex].value;
|
const UID = dropdown.options[dropdown.selectedIndex].value;
|
||||||
const Name = dropdown.options[dropdown.selectedIndex].text;
|
const Name = dropdown.options[dropdown.selectedIndex].text;
|
||||||
|
|
||||||
const installDattoRMM = document.querySelector('input[name="installDattoRMM"]')
|
const installDattoRMM = document.querySelector('input[name="installDattoRMM"]');
|
||||||
const installCyberQP = document.querySelector('input[name="installCyberQP"]');
|
const installCyberQP = document.querySelector('input[name="installCyberQP"]');
|
||||||
const installSplashtop = document.querySelector('input[name="installSplashtop"]');
|
const installSplashtop = document.querySelector('input[name="installSplashtop"]');
|
||||||
const installSVSHelpDesk = document.querySelector('input[name="installSVSHelpDesk"]');
|
const installSVSHelpDesk = document.querySelector('input[name="installSVSHelpDesk"]');
|
||||||
@@ -717,15 +684,11 @@ function GetHtmlContent {
|
|||||||
|
|
||||||
if (installDattoRMM.checked) {
|
if (installDattoRMM.checked) {
|
||||||
const DattoRMMCheckbox = document.querySelectorAll('input[name="dattoRMMOption"]:checked');
|
const DattoRMMCheckbox = document.querySelectorAll('input[name="dattoRMMOption"]:checked');
|
||||||
|
|
||||||
appendLog("Installing selected site RMM...", "cyan");
|
appendLog("Installing selected site RMM...", "cyan");
|
||||||
|
|
||||||
const checkedValues = Array.from(DattoRMMCheckbox).map(c => c.value);
|
const checkedValues = Array.from(DattoRMMCheckbox).map(c => c.value);
|
||||||
|
|
||||||
// Initialize the PowerShell command
|
|
||||||
let installRMMCommand = 'Install-DattoRMM -ApiUrl $ApiUrl -ApiKey $ApiKey -ApiSecretKey $ApiSecretKey';
|
let installRMMCommand = 'Install-DattoRMM -ApiUrl $ApiUrl -ApiKey $ApiKey -ApiSecretKey $ApiSecretKey';
|
||||||
|
|
||||||
// Check individual selections and append flags to the command
|
|
||||||
if (checkedValues.includes('inputVar')) {
|
if (checkedValues.includes('inputVar')) {
|
||||||
installRMMCommand += ' -PushSiteVars';
|
installRMMCommand += ' -PushSiteVars';
|
||||||
}
|
}
|
||||||
@@ -736,83 +699,98 @@ function GetHtmlContent {
|
|||||||
installRMMCommand += ' -SaveCopy';
|
installRMMCommand += ' -SaveCopy';
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = fetch('/installrmm', {
|
fetch('/installrmm', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({ installRMMCommand, UID, Name })
|
||||||
installRMMCommand,
|
|
||||||
UID,
|
|
||||||
Name
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (installCyberQP.checked) {
|
|
||||||
|
|
||||||
fetch('/installCyberQP', { method: 'GET' })
|
if (installCyberQP.checked) {
|
||||||
|
fetch('/installCyberQP', { method: 'GET' });
|
||||||
appendLog("Installing CyberQP", "cyan");
|
appendLog("Installing CyberQP", "cyan");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (installSplashtop.checked) {
|
if (installSplashtop.checked) {
|
||||||
|
fetch('/installSplashtop', { method: 'GET' });
|
||||||
appendLog("Installing Splashtop", "cyan");
|
appendLog("Installing Splashtop", "cyan");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (installSVSHelpDesk.checked) {
|
if (installSVSHelpDesk.checked) {
|
||||||
|
fetch('/installSVSHelpDesk', { method: 'GET' });
|
||||||
appendLog("Installing SVSHelpdesk", "cyan");
|
appendLog("Installing SVSHelpdesk", "cyan");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (installSVSWatchtower.checked) {
|
if (installSVSWatchtower.checked) {
|
||||||
|
fetch('/installSVSWatchtower', { method: 'GET' });
|
||||||
appendLog("Installing SVSWatchtower", "cyan");
|
appendLog("Installing SVSWatchtower", "cyan");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (installThreatLocker.checked) {
|
if (installThreatLocker.checked) {
|
||||||
|
fetch('/installThreatLocker', { method: 'GET' });
|
||||||
appendLog("Installing ThreatLocker", "cyan");
|
appendLog("Installing ThreatLocker", "cyan");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (installRocketCyber.checked) {
|
if (installRocketCyber.checked) {
|
||||||
|
fetch('/installRocketCyber', { method: 'GET' });
|
||||||
appendLog("Installing RocketCyber", "cyan");
|
appendLog("Installing RocketCyber", "cyan");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function endSession() {
|
function endSession() {
|
||||||
appendLog("Session ended. Closing application...", "yellow");
|
appendLog("Session ended. Closing application...", "yellow");
|
||||||
|
|
||||||
fetch('/quit', { method: 'GET' })
|
fetch('/quit', { method: 'GET' })
|
||||||
.then(response => {
|
.then(response => {
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error('Failed to end session');
|
throw new Error('Failed to end session');
|
||||||
}
|
}
|
||||||
// Optionally, close the window or do something else
|
window.close();
|
||||||
window.close()
|
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
appendLog("Error ending session: " + error.message, "red");
|
appendLog("Error ending session: " + error.message, "red");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function appendLog(message, color = "white") {
|
function appendLog(message, color = "white") {
|
||||||
const log = document.createElement('p');
|
const log = document.createElement('p');
|
||||||
log.style.color = color;
|
log.style.color = color;
|
||||||
log.textContent = message;
|
log.textContent = message;
|
||||||
logArea.appendChild(log);
|
document.getElementById('logArea').appendChild(log);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// 3) POLL THE SERVER LOGS (NEW)
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
let lastLogCount = 0;
|
||||||
|
async function fetchLogs() {
|
||||||
|
try {
|
||||||
|
const resp = await fetch('/getLogs');
|
||||||
|
if (!resp.ok) return;
|
||||||
|
const logs = await resp.json(); // array of {Timestamp, Level, Message}
|
||||||
|
|
||||||
|
// Append only new messages
|
||||||
|
for (let i = lastLogCount; i < logs.length; i++) {
|
||||||
|
// We'll display each new line in "white" or a color of your choice
|
||||||
|
appendLog(logs[i].Message, "white");
|
||||||
|
}
|
||||||
|
lastLogCount = logs.length;
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error fetching logs:", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Poll logs every 3 seconds (feel free to adjust)
|
||||||
|
setInterval(fetchLogs, 3000);
|
||||||
|
// -------------------------------------------------------------------
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
"@
|
"@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Save and launch the HTML
|
# Save and launch the HTML
|
||||||
Start-Process "msedge.exe" -ArgumentList "--app=http://localhost:8081/"
|
Start-Process "msedge.exe" -ArgumentList "--app=http://localhost:8081/"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while ($listener.IsListening) {
|
while ($listener.IsListening) {
|
||||||
# Wait for an incoming request
|
|
||||||
$context = $listener.GetContext()
|
$context = $listener.GetContext()
|
||||||
$request = $context.Request
|
$request = $context.Request
|
||||||
$response = $context.Response
|
$response = $context.Response
|
||||||
@@ -820,7 +798,6 @@ try {
|
|||||||
switch ($request.Url.AbsolutePath) {
|
switch ($request.Url.AbsolutePath) {
|
||||||
|
|
||||||
"/" {
|
"/" {
|
||||||
# Serve the main HTML
|
|
||||||
$htmlContent = GetHtmlContent
|
$htmlContent = GetHtmlContent
|
||||||
$buffer = [System.Text.Encoding]::UTF8.GetBytes($htmlContent)
|
$buffer = [System.Text.Encoding]::UTF8.GetBytes($htmlContent)
|
||||||
$response.ContentType = "text/html"
|
$response.ContentType = "text/html"
|
||||||
@@ -831,17 +808,13 @@ try {
|
|||||||
|
|
||||||
"/getn8npw" {
|
"/getn8npw" {
|
||||||
if ($request.HttpMethod -eq "POST") {
|
if ($request.HttpMethod -eq "POST") {
|
||||||
# Parse the received JSON
|
|
||||||
$bodyStream = New-Object IO.StreamReader $request.InputStream
|
$bodyStream = New-Object IO.StreamReader $request.InputStream
|
||||||
$body = $bodyStream.ReadToEnd()
|
$body = $bodyStream.ReadToEnd()
|
||||||
$data = ConvertFrom-Json $body
|
$data = ConvertFrom-Json $body
|
||||||
$password = $data.password
|
$password = $data.password
|
||||||
|
|
||||||
Get-N8nWebhookData -AuthHeaderValue $password
|
Get-N8nWebhookData -AuthHeaderValue $password
|
||||||
|
|
||||||
# Fetch the list of Datto RMM client sites
|
|
||||||
$sites = Install-DattoRMM -ApiUrl $ApiUrl -ApiKey $ApiKey -ApiSecretKey $ApiSecretKey -FetchSitesOnly
|
$sites = Install-DattoRMM -ApiUrl $ApiUrl -ApiKey $ApiKey -ApiSecretKey $ApiSecretKey -FetchSitesOnly
|
||||||
|
|
||||||
if (-not $sites) {
|
if (-not $sites) {
|
||||||
Write-Host "No sites returned. Please check the API." -ForegroundColor Red
|
Write-Host "No sites returned. Please check the API." -ForegroundColor Red
|
||||||
$response.StatusCode = 500
|
$response.StatusCode = 500
|
||||||
@@ -850,15 +823,10 @@ try {
|
|||||||
$response.OutputStream.Close()
|
$response.OutputStream.Close()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
# Convert the array (or object) in $sites to JSON
|
|
||||||
$responseData = $sites | ConvertTo-Json
|
$responseData = $sites | ConvertTo-Json
|
||||||
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseData)
|
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseData)
|
||||||
|
|
||||||
# Set the response headers
|
|
||||||
$response.ContentType = "application/json"
|
$response.ContentType = "application/json"
|
||||||
$response.ContentLength64 = $buffer.Length
|
$response.ContentLength64 = $buffer.Length
|
||||||
|
|
||||||
$response.OutputStream.Write($buffer, 0, $buffer.Length)
|
$response.OutputStream.Write($buffer, 0, $buffer.Length)
|
||||||
$response.OutputStream.Close()
|
$response.OutputStream.Close()
|
||||||
}
|
}
|
||||||
@@ -871,7 +839,6 @@ try {
|
|||||||
$selectedSite = ConvertFrom-Json $body
|
$selectedSite = ConvertFrom-Json $body
|
||||||
Invoke-Expression $selectedSite.installRMMCommand
|
Invoke-Expression $selectedSite.installRMMCommand
|
||||||
|
|
||||||
# Return a simple success response
|
|
||||||
$responseString = "RMM install triggered."
|
$responseString = "RMM install triggered."
|
||||||
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
|
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
|
||||||
$response.ContentType = "text/plain"
|
$response.ContentType = "text/plain"
|
||||||
@@ -885,7 +852,6 @@ try {
|
|||||||
if ($request.HttpMethod -eq "GET") {
|
if ($request.HttpMethod -eq "GET") {
|
||||||
Install-CyberQP
|
Install-CyberQP
|
||||||
}
|
}
|
||||||
# Return something
|
|
||||||
$responseString = "Install CyberQP triggered."
|
$responseString = "Install CyberQP triggered."
|
||||||
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
|
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
|
||||||
$response.ContentType = "text/plain"
|
$response.ContentType = "text/plain"
|
||||||
@@ -954,41 +920,50 @@ try {
|
|||||||
$response.OutputStream.Close()
|
$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" {
|
"/quit" {
|
||||||
if ($request.HttpMethod -eq "GET") {
|
if ($request.HttpMethod -eq "GET") {
|
||||||
# Return a "shutting down" message
|
$responseString = "Server shutting down."
|
||||||
$responseString = "Server shutting down."
|
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
|
||||||
$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
|
$response.ContentType = "text/plain"
|
||||||
$response.ContentType = "text/plain"
|
$response.ContentLength64 = $buffer.Length
|
||||||
$response.ContentLength64 = $buffer.Length
|
$response.OutputStream.Write($buffer, 0, $buffer.Length)
|
||||||
$response.OutputStream.Write($buffer, 0, $buffer.Length)
|
$response.OutputStream.Close()
|
||||||
$response.OutputStream.Close()
|
Write-Host $responseString
|
||||||
Write-Host $responseString
|
$listener.stop()
|
||||||
$listener.stop()
|
break
|
||||||
break # exit the while loop
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
default {
|
default {
|
||||||
# Handle unknown routes
|
|
||||||
$response.StatusCode = 404
|
$response.StatusCode = 404
|
||||||
$response.StatusDescription = "Not Found"
|
$response.StatusDescription = "Not Found"
|
||||||
$buffer = [System.Text.Encoding]::UTF8.GetBytes("404 - Not Found")
|
$buffer = [System.Text.Encoding]::UTF8.GetBytes("404 - Not Found")
|
||||||
$response.OutputStream.Write($buffer, 0, $buffer.Length)
|
$response.OutputStream.Write($buffer, 0, $buffer.Length)
|
||||||
$response.OutputStream.Close()
|
$response.OutputStream.Close()
|
||||||
}
|
}
|
||||||
} # end switch
|
}
|
||||||
} # end while
|
}
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
Write-Host "Error: $($_.Exception.Message)"
|
Write-Host "Error: $($_.Exception.Message)"
|
||||||
|
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
$listener.Stop()
|
$listener.Stop()
|
||||||
$listener.Close()
|
$listener.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user