From 3c0b904c9ec25c7d2aa16fd19ae508d1e4edcc0f Mon Sep 17 00:00:00 2001 From: syelle Date: Fri, 28 Nov 2025 19:35:44 -0500 Subject: [PATCH] added headless offboard --- samy.ps1 | 70 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/samy.ps1 b/samy.ps1 index d245424..d29a219 100644 --- a/samy.ps1 +++ b/samy.ps1 @@ -68,6 +68,9 @@ .PARAMETER SaveCopy Switch to save a copy of the downloaded Datto RMM installer into C:\Temp. +.PARAMETER Offboard + Switch that runs every off-boarding task sequentially (same behavior as checking "Select All" on the Off-Boarding tab) without launching the web UI. + .PARAMETER SiteUID The unique identifier of the Datto RMM site. Mandatory when performing install or variable-push. @@ -141,6 +144,11 @@ .EXAMPLE & ([ScriptBlock]::Create((iwr 'sm.svstools.com').Content)) -Cleanup +.EXAMPLE +& ([ScriptBlock]::Create((iwr 'samy.svstools.ca').Content)) -Offboard + + # Runs the off-boarding tasks in sequence without launching the UI. + #> #region Safely bypass Restricted Execution Policy # ─── Safely bypass Restricted Execution Policy ─── @@ -184,6 +192,9 @@ $ConfirmPreference = 'None' # remove Toolkit [Parameter(Mandatory,ParameterSetName='Cleanup')][switch]$Cleanup, + # headless offboarding + [Parameter(Mandatory,ParameterSetName='Offboard')][switch]$Offboard, + # ───────────────────────────────────────────────────────── # Datto headless mode @@ -1142,6 +1153,9 @@ $jsContent function Respond-Text { param($Context, $Text) + if (-not $Context -or -not $Context.Response) { + return + } $bytes = [Text.Encoding]::UTF8.GetBytes($Text) $Context.Response.ContentType = 'text/plain' $Context.Response.ContentLength64 = $bytes.Length @@ -1155,6 +1169,9 @@ $jsContent [Parameter(Mandatory = $true)][object] $Context, [Parameter(Mandatory = $true)][string] $Html ) + if (-not $Context -or -not $Context.Response) { + return + } $bytes = [Text.Encoding]::UTF8.GetBytes($Html) $Context.Response.ContentType = 'text/html' $Context.Response.ContentLength64 = $bytes.Length @@ -1162,8 +1179,11 @@ $jsContent $Context.Response.OutputStream.Close() } - function Respond-JSON { + function Respond-JSON { param($Context, $Object) + if (-not $Context -or -not $Context.Response) { + return + } $json = $Object | ConvertTo-Json -Depth 5 $bytes = [Text.Encoding]::UTF8.GetBytes($json) $Context.Response.ContentType = 'application/json' @@ -1755,35 +1775,37 @@ function Install-DattoRMM { } -<# - - 'UI' { - $url = "http://localhost:$Port/" - Write-LogHybrid "Starting ScriptAutomationMonkey UI on $url" Info Startup - # Open the UI in a separate PowerShell job so Start-Server can block safely. - try { - Start-Job -Name 'OpenScriptAutomationMonkeyUI' -ScriptBlock { - param($u) - Start-Sleep -Milliseconds 300 - try { - if (Get-Command -Name 'msedge.exe' -ErrorAction SilentlyContinue) { - Start-Process -FilePath 'msedge.exe' -ArgumentList "--app=$u" - } else { - Start-Process -FilePath $u - } - } catch { } - } -ArgumentList $url | Out-Null - } catch { - Write-LogHybrid "Failed to schedule browser launch: $($_.Exception.Message)" Warning Startup -LogToEvent + + 'Offboard' { + Write-LogHybrid "Headless offboarding requested" Info OffBoard -LogToEvent + $offboardTasks = $Global:SamyTasks | Where-Object Page -EQ 'offboard' + if (-not $offboardTasks) { + Write-LogHybrid "No offboard tasks configured" Warning OffBoard -LogToEvent + return } - # Now start the blocking listener loop - Start-Server + if (-not $PSCmdlet.ShouldProcess("Full off-boarding flow", "Execute every offboard task")) { + return + } + + foreach ($task in $offboardTasks) { + try { + Write-LogHybrid "Running offboard task: $($task.Label)" Info OffBoard -LogToEvent + if (-not (Get-Command $task.HandlerFn -ErrorAction SilentlyContinue)) { + Write-LogHybrid "Missing handler $($task.HandlerFn)" Error OffBoard -LogToEvent + continue + } + & $task.HandlerFn $null + } catch { + Write-LogHybrid "Offboard task $($task.Label) failed: $($_.Exception.Message)" Error OffBoard -LogToEvent + } + } + + Write-LogHybrid "Headless offboarding complete" Success OffBoard -LogToEvent return } -#> 'UI' { $url = "http://localhost:$Port/"