Update StackMonkey.ps1
This commit is contained in:
317
StackMonkey.ps1
317
StackMonkey.ps1
@@ -87,6 +87,21 @@
|
||||
# ─────────────────────────────────────────────────────────────────────────
|
||||
# 1) ENTRYPOINT + PARAMETER DECLARATION
|
||||
# ─────────────────────────────────────────────────────────────────────────
|
||||
function Invoke-ScriptMonkey {
|
||||
[CmdletBinding(
|
||||
DefaultParameterSetName='UI',
|
||||
SupportsShouldProcess=$true,
|
||||
ConfirmImpact='Medium'
|
||||
)]
|
||||
param(
|
||||
[Parameter(Mandatory,ParameterSetName='Toolkit')] [switch]$SilentInstall,
|
||||
[Parameter(Mandatory,ParameterSetName='DattoFetch')]
|
||||
[Parameter(Mandatory,ParameterSetName='DattoInstall')]
|
||||
[string]$N8nPassword,
|
||||
…
|
||||
)
|
||||
|
||||
# — all of your modules, helpers, functions, etc. go here —
|
||||
|
||||
[CmdletBinding(
|
||||
DefaultParameterSetName='UI',
|
||||
@@ -122,19 +137,19 @@
|
||||
|
||||
#region — guarantee NuGet provider is present without prompting
|
||||
|
||||
# ─── Top of script ───
|
||||
Import-Module PackageManagement -Force -ErrorAction SilentlyContinue | Out-Null
|
||||
Import-Module PowerShellGet -Force -ErrorAction SilentlyContinue | Out-Null
|
||||
# ─── Top of script ───
|
||||
Import-Module PackageManagement -Force -ErrorAction SilentlyContinue | Out-Null
|
||||
Import-Module PowerShellGet -Force -ErrorAction SilentlyContinue | Out-Null
|
||||
|
||||
# ─── ensure TLS 1.2 + no prompts ───
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
$ConfirmPreference = 'None'
|
||||
# ─── ensure TLS 1.2 + no prompts ───
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
$ConfirmPreference = 'None'
|
||||
|
||||
# check if NuGet exists (no output—assigned to $nuget)
|
||||
$nuget = Get-PackageProvider -Name NuGet -ListAvailable -ErrorAction SilentlyContinue
|
||||
# check if NuGet exists (no output—assigned to $nuget)
|
||||
$nuget = Get-PackageProvider -Name NuGet -ListAvailable -ErrorAction SilentlyContinue
|
||||
|
||||
if (-not $nuget) {
|
||||
if (-not $nuget) {
|
||||
# install it (again, assignment suppresses the table)
|
||||
Install-PackageProvider `
|
||||
-Name NuGet `
|
||||
@@ -146,26 +161,26 @@ if (-not $nuget) {
|
||||
# re-query just for version info
|
||||
$found = Get-PackageProvider -Name NuGet -ListAvailable
|
||||
Write-Host "Installed NuGet provider v$($found.Version)" -ForegroundColor Green
|
||||
}
|
||||
else {
|
||||
}
|
||||
else {
|
||||
Write-Host "NuGet provider already present (v$($found.Version))" -ForegroundColor DarkGray
|
||||
}
|
||||
}
|
||||
|
||||
# now import it silently
|
||||
Import-PackageProvider -Name NuGet -Force -ErrorAction SilentlyContinue | Out-Null
|
||||
# now import it silently
|
||||
Import-PackageProvider -Name NuGet -Force -ErrorAction SilentlyContinue | Out-Null
|
||||
|
||||
# ensure trust PSGallery without its own output (so you don't get “untrusted repository” prompt
|
||||
$gallery = Get-PSRepository -Name PSGallery -ErrorAction SilentlyContinue
|
||||
if ($gallery.InstallationPolicy -ne 'Trusted') {
|
||||
# ensure trust PSGallery without its own output (so you don't get “untrusted repository” prompt
|
||||
$gallery = Get-PSRepository -Name PSGallery -ErrorAction SilentlyContinue
|
||||
if ($gallery.InstallationPolicy -ne 'Trusted') {
|
||||
Set-PSRepository `
|
||||
-Name PSGallery `
|
||||
-InstallationPolicy Trusted `
|
||||
-ErrorAction SilentlyContinue | Out-Null
|
||||
|
||||
Write-Host "PSGallery marked as Trusted" -ForegroundColor Green
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────
|
||||
@@ -178,8 +193,8 @@ if ($gallery.InstallationPolicy -ne 'Trusted') {
|
||||
# Configurable endpoints
|
||||
$Global:DattoWebhookUrl = 'https://automate.svstools.ca/webhook/svsmspkit'
|
||||
|
||||
#region Get-DattoApiCredentials
|
||||
function Get-DattoApiCredentials {
|
||||
#region Get-DattoApiCredentials
|
||||
function Get-DattoApiCredentials {
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[Parameter(Mandatory)][string]$Password
|
||||
@@ -199,9 +214,9 @@ function Get-DattoApiCredentials {
|
||||
Write-LogHybrid "Failed to fetch API credentials: $($_.Exception.Message)" Error DattoAuth
|
||||
return $null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Get-DattoRmmSites {
|
||||
function Get-DattoRmmSites {
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -268,15 +283,15 @@ function Get-DattoRmmSites {
|
||||
catch {
|
||||
Throw "Failed to fetch sites from API: $_"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Initialize a global in-memory log cache
|
||||
if (-not $Global:LogCache -or -not ($Global:LogCache -is [System.Collections.ArrayList])) {
|
||||
# Initialize a global in-memory log cache
|
||||
if (-not $Global:LogCache -or -not ($Global:LogCache -is [System.Collections.ArrayList])) {
|
||||
$Global:LogCache = [System.Collections.ArrayList]::new()
|
||||
}
|
||||
}
|
||||
|
||||
# Core Write-Log function (advanced with event-log support)
|
||||
# Core Write-Log function (advanced with event-log support)
|
||||
function Write-LogHelper {
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
@@ -318,12 +333,12 @@ if (-not $Global:LogCache -or -not ($Global:LogCache -is [System.Collections.Arr
|
||||
}
|
||||
|
||||
if ($PassThru) { return $entry }
|
||||
}
|
||||
}
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────
|
||||
# WRITE-LOG HYBRID (single definition, chooses at runtime)
|
||||
# ─────────────────────────────────────────────────────────────────────────
|
||||
function Write-LogHybrid {
|
||||
# ─────────────────────────────────────────────────────────────────────────
|
||||
# WRITE-LOG HYBRID (single definition, chooses at runtime)
|
||||
# ─────────────────────────────────────────────────────────────────────────
|
||||
function Write-LogHybrid {
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][string]$Message,
|
||||
@@ -341,26 +356,26 @@ function Write-LogHybrid {
|
||||
# fall back to your helper
|
||||
Write-LogHelper -Message $Message -Level $Level -TaskCategory $TaskCategory -LogToEvent:$LogToEvent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
|
||||
# STACK = Scripted Tooling for Automated Client Kickoff
|
||||
# MONKEY = Module-based Onboarding & Next-step Kickoff Engine Yoke
|
||||
# Conveys the idea of coupling tasks together and keeping them under control.
|
||||
# STACK = Scripted Tooling for Automated Client Kickoff
|
||||
# MONKEY = Module-based Onboarding & Next-step Kickoff Engine Yoke
|
||||
# Conveys the idea of coupling tasks together and keeping them under control.
|
||||
|
||||
#region Config & Task Definitions
|
||||
#region Config & Task Definitions
|
||||
|
||||
# Define every task once here:
|
||||
# Id → checkbox HTML `id`
|
||||
# Name → URL path (`/Name`)
|
||||
# Label → user-visible text
|
||||
# HandlerFn → the PowerShell function to invoke
|
||||
# Page → which tab/page it appears on
|
||||
# Define every task once here:
|
||||
# Id → checkbox HTML `id`
|
||||
# Name → URL path (`/Name`)
|
||||
# Label → user-visible text
|
||||
# HandlerFn → the PowerShell function to invoke
|
||||
# Page → which tab/page it appears on
|
||||
|
||||
$Global:Tasks = @(
|
||||
$Global:Tasks = @(
|
||||
# On-Boarding, left column
|
||||
@{ Id='setSVSPowerplan'; Name='setSVSPowerplan'; Label='Set SVS Powerplan'; HandlerFn='Handle-setSVSPowerPlan'; Page='onboard'; Column='left' },
|
||||
@{ Id='installSVSMSPModule'; Name='installSVSMSPModule'; Label='Install SVSMSP Module'; HandlerFn='Handle-InstallSVSMSP'; Page='onboard'; Column='left' },
|
||||
@@ -390,28 +405,28 @@ $Global:Tasks = @(
|
||||
|
||||
# SVS Apps
|
||||
@{ Id='wingetLastpass'; Name='wingetLastpass'; Label='LastPass Desktop App'; HandlerFn='Install-WingetLastPass'; Page='SVSApps' }
|
||||
)
|
||||
)
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
|
||||
# If we got here, it's the UI set—launch browser + listener:
|
||||
# If we got here, it's the UI set—launch browser + listener:
|
||||
# ——— UI fallback starts here ———
|
||||
Write-LogHybrid "Launching UI" Info Startup
|
||||
|
||||
|
||||
#region Handler Stubs
|
||||
#region Handler Stubs
|
||||
|
||||
function Respond-Text {
|
||||
function Respond-Text {
|
||||
param($Context, $Text)
|
||||
$bytes = [Text.Encoding]::UTF8.GetBytes($Text)
|
||||
$Context.Response.ContentType = 'text/plain'
|
||||
$Context.Response.ContentLength64 = $bytes.Length
|
||||
$Context.Response.OutputStream.Write($bytes,0,$bytes.Length)
|
||||
$Context.Response.OutputStream.Close()
|
||||
}
|
||||
}
|
||||
|
||||
function Respond-HTML {
|
||||
function Respond-HTML {
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][object] $Context,
|
||||
@@ -422,10 +437,10 @@ function Respond-HTML {
|
||||
$Context.Response.ContentLength64 = $bytes.Length
|
||||
$Context.Response.OutputStream.Write($bytes, 0, $bytes.Length)
|
||||
$Context.Response.OutputStream.Close()
|
||||
}
|
||||
}
|
||||
|
||||
# new helper to return JSON
|
||||
function Respond-JSON {
|
||||
# new helper to return JSON
|
||||
function Respond-JSON {
|
||||
param($Context, $Object)
|
||||
$json = $Object | ConvertTo-Json -Depth 5
|
||||
$bytes = [Text.Encoding]::UTF8.GetBytes($json)
|
||||
@@ -433,11 +448,11 @@ function Respond-JSON {
|
||||
$Context.Response.ContentLength64 = $bytes.Length
|
||||
$Context.Response.OutputStream.Write($bytes,0,$bytes.Length)
|
||||
$Context.Response.OutputStream.Close()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region Install-DattoRMM-Helper
|
||||
function Install-DattoRMM-Helper {
|
||||
#region Install-DattoRMM-Helper
|
||||
function Install-DattoRMM-Helper {
|
||||
param (
|
||||
[string]$ApiUrl,
|
||||
[string]$ApiKey,
|
||||
@@ -487,12 +502,12 @@ function Install-DattoRMM-Helper {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region SVS Module
|
||||
#region SVS Module
|
||||
|
||||
function Install-SVSMSP {
|
||||
function Install-SVSMSP {
|
||||
param (
|
||||
[switch] $Cleanup,
|
||||
[switch] $InstallToolkit,
|
||||
@@ -528,14 +543,14 @@ function Install-SVSMSP {
|
||||
}
|
||||
# default if no switch passed:
|
||||
Perform-ToolkitInstallation
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
# POST /getpw → read JSON body, call helper, return JSON
|
||||
# POST /getpw → read JSON body, call helper, return JSON
|
||||
|
||||
|
||||
function Handle-FetchSites {
|
||||
function Handle-FetchSites {
|
||||
param($Context)
|
||||
|
||||
# 1) Read incoming JSON (using block auto-disposes the reader)
|
||||
@@ -558,7 +573,7 @@ function Handle-FetchSites {
|
||||
# 2) Fetch your Datto API creds from the webhook
|
||||
Write-LogHybrid "Calling webhook for Datto credentials…" "Info" "FetchSites"
|
||||
|
||||
try {
|
||||
try {
|
||||
$creds = Get-DattoApiCredentials -Password $pw
|
||||
if (-not $creds) {
|
||||
Write-LogHybrid "Webhook returned no credentials" Error FetchSites
|
||||
@@ -572,11 +587,11 @@ try {
|
||||
$Global:ApiSecretKey = $creds.ApiSecretKey
|
||||
|
||||
Write-LogHybrid "Fetched and stored API credentials." Success FetchSites
|
||||
} catch {
|
||||
} catch {
|
||||
Write-LogHybrid "Credential-fetch error: $($_.Exception.Message)" Error FetchSites -LogToEvent
|
||||
returnRespondEmpty $Context 500
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# 3) Exchange for a bearer token
|
||||
@@ -624,12 +639,12 @@ try {
|
||||
$Context.Response.ContentLength64 = $bytes.Length
|
||||
$Context.Response.OutputStream.Write($bytes, 0, $bytes.Length)
|
||||
$Context.Response.OutputStream.Close()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Helper function to consistently return an empty JSON array
|
||||
function returnRespondEmpty {
|
||||
# Helper function to consistently return an empty JSON array
|
||||
function returnRespondEmpty {
|
||||
param(
|
||||
[Parameter(Mandatory)][object]$Context,
|
||||
[Parameter(Mandatory)][ValidateRange(100,599)][int]$StatusCode = 500
|
||||
@@ -645,12 +660,12 @@ function returnRespondEmpty {
|
||||
# Write and close
|
||||
$Context.Response.OutputStream.Write($empty, 0, $empty.Length)
|
||||
$Context.Response.OutputStream.Close()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
# On-boarding handlers
|
||||
function Handle-SetSVSPowerPlan {
|
||||
# On-boarding handlers
|
||||
function Handle-SetSVSPowerPlan {
|
||||
param($Context)
|
||||
|
||||
# 1) call into your module
|
||||
@@ -659,9 +674,9 @@ function Handle-SetSVSPowerPlan {
|
||||
# 2) log & write back a simple text response
|
||||
Write-LogHybrid "PowerPlan set" "Success" "OnBoard"
|
||||
Respond-Text $Context "PowerPlan applied"
|
||||
}
|
||||
}
|
||||
|
||||
function Handle-InstallSVSMSP {
|
||||
function Handle-InstallSVSMSP {
|
||||
param($Context)
|
||||
Write-LogHybrid "HTTP trigger: Handle-InstallSVSMSP" "Info" "OnBoard"
|
||||
try {
|
||||
@@ -671,9 +686,9 @@ function Handle-InstallSVSMSP {
|
||||
Write-LogHybrid "Error in Install-SVSMSP: $_" "Error" "OnBoard"
|
||||
Respond-Text $Context "ERROR: $_"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Handle-InstallCyberQP {
|
||||
function Handle-InstallCyberQP {
|
||||
param($Context)
|
||||
|
||||
# 1) call into your module
|
||||
@@ -682,9 +697,9 @@ function Handle-InstallCyberQP {
|
||||
# 2) log & write back a simple text response
|
||||
Write-LogHybrid "CyberQP installed" "Success" "OnBoard"
|
||||
Respond-Text $Context "CyberQP installed"
|
||||
}
|
||||
}
|
||||
|
||||
function Handle-InstallThreatLocker {
|
||||
function Handle-InstallThreatLocker {
|
||||
param($Context)
|
||||
|
||||
# 1) call into your module
|
||||
@@ -693,9 +708,9 @@ function Handle-InstallThreatLocker {
|
||||
# 2) log & write back a simple text response
|
||||
Write-LogHybrid "ThreatLocker installed" "Success" "OnBoard"
|
||||
Respond-Text $Context "ThreatLocker installed"
|
||||
}
|
||||
}
|
||||
|
||||
function Handle-InstallRocketCyber {
|
||||
function Handle-InstallRocketCyber {
|
||||
param($Context)
|
||||
|
||||
# 1) call into your module
|
||||
@@ -704,9 +719,9 @@ function Handle-InstallRocketCyber {
|
||||
# 2) log & write back a simple text response
|
||||
Write-LogHybrid "RocketCyber installed" "Success" "OnBoard"
|
||||
Respond-Text $Context "RocketCyber installed"
|
||||
}
|
||||
}
|
||||
|
||||
function Handle-InstallSVSHelpDesk {
|
||||
function Handle-InstallSVSHelpDesk {
|
||||
param($Context)
|
||||
|
||||
# 1) call into your module
|
||||
@@ -715,9 +730,9 @@ function Handle-InstallSVSHelpDesk {
|
||||
# 2) log & write back a simple text response
|
||||
Write-LogHybrid "SVS HelpDesk installed" "Success" "OnBoard"
|
||||
Respond-Text $Context "SVS HelpDesk installed"
|
||||
}
|
||||
}
|
||||
|
||||
function Handle-InstallDattoRMM {
|
||||
function Handle-InstallDattoRMM {
|
||||
param($Context)
|
||||
$req = $Context.Request
|
||||
$resp = $Context.Response
|
||||
@@ -761,11 +776,11 @@ function Handle-InstallDattoRMM {
|
||||
$resp.ContentLength64 = $b.Length
|
||||
$resp.OutputStream.Write($b,0,$b.Length)
|
||||
$resp.OutputStream.Close()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Off-boarding handlers
|
||||
function Handle-UninstallCyberQP {
|
||||
# Off-boarding handlers
|
||||
function Handle-UninstallCyberQP {
|
||||
param($Context)
|
||||
|
||||
# 1) call into your module
|
||||
@@ -773,33 +788,33 @@ function Handle-UninstallCyberQP {
|
||||
|
||||
Write-LogHybrid "CyberQP uninstalled" "Success" "OffBoard"
|
||||
Respond-Text $Context "CyberQP uninstalled"
|
||||
}
|
||||
}
|
||||
|
||||
function Cleanup-SVSMSP {
|
||||
function Cleanup-SVSMSP {
|
||||
param($Context)
|
||||
Write-LogHybrid "SVSMSP cleaned up" "Success" "OffBoard"
|
||||
Respond-Text $Context "SVSMSP cleaned up"
|
||||
}
|
||||
}
|
||||
|
||||
# Tweaks handler
|
||||
function Disable-Animations {
|
||||
# Tweaks handler
|
||||
function Disable-Animations {
|
||||
param($Context)
|
||||
Write-LogHybrid "Animations disabled" "Success" "Tweaks"
|
||||
Respond-Text $Context "Animations disabled"
|
||||
}
|
||||
}
|
||||
|
||||
# SVSApps handler
|
||||
function Install-WingetLastPass {
|
||||
# SVSApps handler
|
||||
function Install-WingetLastPass {
|
||||
param($Context)
|
||||
Write-LogHybrid "Winget LastPass installed" "Success" "SVSApps"
|
||||
Respond-Text $Context "Winget LastPass installed"
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region UI Generation
|
||||
#region UI Generation
|
||||
|
||||
function Build-Checkboxes {
|
||||
function Build-Checkboxes {
|
||||
param($Page, $Column)
|
||||
|
||||
(
|
||||
@@ -826,37 +841,37 @@ function Build-Checkboxes {
|
||||
) -join "`n"
|
||||
|
||||
$html += @"
|
||||
<div id='${taskId}OptionsContainer' style='display:none; margin-top:4px;'>
|
||||
$subHtml
|
||||
</div>
|
||||
"@
|
||||
<div id='${taskId}OptionsContainer' style='display:none; margin-top:4px;'>
|
||||
$subHtml
|
||||
</div>
|
||||
"@
|
||||
}
|
||||
|
||||
$html
|
||||
}
|
||||
) -join "`n"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
### Get SVSMSP module version to display in the UI
|
||||
function Get-ModuleVersionHtml {
|
||||
### Get SVSMSP module version to display in the UI
|
||||
function Get-ModuleVersionHtml {
|
||||
$mod = Get-Module -ListAvailable -Name SVSMSP | Sort-Object Version -Descending | Select-Object -First 1
|
||||
if ($mod) {
|
||||
return "<div style='color:#bbb; font-size:0.9em; margin-top:1em;'>Module Version: $($mod.Version)</div>"
|
||||
}
|
||||
return "<div style='color:#f66;'>SVSMSP_Module not found</div>"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function Get-UIHtml {
|
||||
function Get-UIHtml {
|
||||
param([string]$Page = 'onboard')
|
||||
|
||||
#
|
||||
# 1) Inline your full original CSS here
|
||||
#
|
||||
$style = @'
|
||||
<style>
|
||||
$style = @'
|
||||
<style>
|
||||
:root {
|
||||
/* Cool Palette */
|
||||
--background-color: rgba(18, 18, 18, 1);
|
||||
@@ -1011,8 +1026,8 @@ $style = @'
|
||||
.container { flex-direction:column; }
|
||||
.sidebar { width:100%; }
|
||||
}
|
||||
</style>
|
||||
'@
|
||||
</style>
|
||||
'@
|
||||
|
||||
$script = @'
|
||||
<script>
|
||||
@@ -1267,22 +1282,22 @@ $style = @'
|
||||
|
||||
</script>
|
||||
|
||||
'@
|
||||
'@
|
||||
|
||||
#
|
||||
# 3) The HTML skeleton with placeholders
|
||||
#
|
||||
$htmlTemplate = @"
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
$htmlTemplate = @"
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<title>Script Monkey</title>
|
||||
<link rel="icon" href="https://git.svstools.com/syelle/Logo/raw/branch/main/SVS_Favicon.ico">
|
||||
$style
|
||||
</head>
|
||||
<body>
|
||||
</head>
|
||||
<body>
|
||||
<div class="logo-container">
|
||||
<div class="logo-left">
|
||||
<img src="https://git.svstools.com/syelle/Logo/raw/branch/main/SVS_logo.svg" alt="SVS Logo">
|
||||
@@ -1330,32 +1345,32 @@ $htmlTemplate = @"
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="dattoRmmContainer" style="display:none; margin-bottom:1em;">
|
||||
<div id="dattoRmmContainer" style="display:none; margin-bottom:1em;">
|
||||
<label for="dattoDropdown">Select a Datto RMM site:</label>
|
||||
<select id="dattoDropdown" style="width:100%;">
|
||||
<option disabled selected>Fetching sites...</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="offboardTab" class="tab-content">
|
||||
<h2>Off-Boarding</h2>
|
||||
<div class="columns-container">
|
||||
{{offboardCheckboxes}}
|
||||
{{offboardCheckboxes}}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div id="tweaksTab" class="tab-content">
|
||||
<h2>Tweaks</h2>
|
||||
<div class="columns-container">
|
||||
{{tweaksCheckboxes}}
|
||||
{{tweaksCheckboxes}}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div id="SVSAppsTab" class="tab-content">
|
||||
<h2>SVS APPs</h2>
|
||||
<div class="columns-container">
|
||||
{{appsCheckboxes}}
|
||||
{{appsCheckboxes}}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -1367,10 +1382,10 @@ $htmlTemplate = @"
|
||||
<button class="exit-button" onclick="endSession()">Exit</button>
|
||||
<button class="run-button" onclick="triggerInstall()">Run Selected</button>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
"@
|
||||
"@
|
||||
|
||||
#
|
||||
# 4) Build the checkbox HTML and tasks JS from $Global:Tasks
|
||||
@@ -1408,26 +1423,26 @@ $htmlTemplate = @"
|
||||
|
||||
|
||||
return $html
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
|
||||
#region HTTP Listener & Routing
|
||||
#region HTTP Listener & Routing
|
||||
|
||||
# Handle shutdown command
|
||||
if ($path -eq 'quit') {
|
||||
# Handle shutdown command
|
||||
if ($path -eq 'quit') {
|
||||
Write-LogHybrid "Shutdown requested" "Info" "Server"
|
||||
Respond-Text $Context "Server shutting down."
|
||||
# This will break out of the while loop in Start-Server
|
||||
$Global:Listener.Stop()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
# Sends the HTML for a given page or invokes a task handler
|
||||
function Dispatch-Request {
|
||||
# Sends the HTML for a given page or invokes a task handler
|
||||
function Dispatch-Request {
|
||||
param($Context)
|
||||
|
||||
# figure out the path
|
||||
@@ -1466,11 +1481,11 @@ function Dispatch-Request {
|
||||
# ---- 404 ----
|
||||
$Context.Response.StatusCode = 404
|
||||
Respond-Text $Context '404 - Not Found'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Starts the HTTP listener loop
|
||||
function Start-Server {
|
||||
# Starts the HTTP listener loop
|
||||
function Start-Server {
|
||||
# make it accessible to Dispatch-Request
|
||||
$Global:Listener = [System.Net.HttpListener]::new()
|
||||
$Global:Listener.Prefixes.Add("http://localhost:$Port/")
|
||||
@@ -1491,16 +1506,16 @@ function Start-Server {
|
||||
$Global:Listener.Close()
|
||||
Write-LogHybrid "Listener closed." "Info" "Server"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region ScriptMonkey run silently Entrypoint
|
||||
#region ScriptMonkey run silently Entrypoint
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────
|
||||
# 3) MAIN LOGIC (Toolkit vs DattoFetch vs DattoInstall vs UI)
|
||||
# ─────────────────────────────────────────────────────────────────────────
|
||||
# ─────────────────────────────────────────────────────────────────────────
|
||||
# 3) MAIN LOGIC (Toolkit vs DattoFetch vs DattoInstall vs UI)
|
||||
# ─────────────────────────────────────────────────────────────────────────
|
||||
|
||||
switch ($PSCmdlet.ParameterSetName) {
|
||||
'Toolkit' {
|
||||
@@ -1561,6 +1576,8 @@ function Start-Server {
|
||||
}
|
||||
#endregion ScriptMonkey run silently Entrypoint
|
||||
|
||||
Invoke-ScriptMonkey @PSBoundParameters
|
||||
|
||||
} # <— end of Invoke-ScriptMonkey
|
||||
|
||||
|
||||
Invoke-ScriptMonkey @PSBoundParameters
|
||||
Reference in New Issue
Block a user