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