From 9863b2322308db4705debc1e5390561c49ef5f9c Mon Sep 17 00:00:00 2001 From: Stephan Yelle Date: Wed, 17 Dec 2025 20:17:50 -0500 Subject: [PATCH] Delete samy-mini.ps1 --- samy-mini.ps1 | 396 -------------------------------------------------- 1 file changed, 396 deletions(-) delete mode 100644 samy-mini.ps1 diff --git a/samy-mini.ps1 b/samy-mini.ps1 deleted file mode 100644 index 8062d2b..0000000 --- a/samy-mini.ps1 +++ /dev/null @@ -1,396 +0,0 @@ -<# -.SYNOPSIS - Script Automation Monkey (SAMY) main entry point. - -.DESCRIPTION - This file is now the orchestration layer only. It handles: - - Execution policy bypass for restricted environments - - Global config (branch, repo base, URLs) - - Loading subsystem scripts (logging, SVSMSP, Datto, printers, UI, HTTP, etc.) - - Exposing Invoke-ScriptAutomationMonkey with parameter sets for: - - UI - - Toolkit-only install - - Toolkit cleanup - - Headless Datto site fetch - - Headless Datto install - - Headless offboarding - - The iwr | iex glue at the bottom so remote calls still work. - - All heavy logic lives in the Samy.*.ps1 subsystem files that are dot-sourced or - loaded from your Git repo, now under a "module" subfolder. -#> - -#region Safely bypass Restricted Execution Policy - -if ($ExecutionContext.SessionState.LanguageMode -ne 'FullLanguage' -or - (Get-ExecutionPolicy) -eq 'Restricted') { - - Write-Host "[Info] Relaunching with ExecutionPolicy Bypass..." -ForegroundColor Yellow - - if ($PSCommandPath) { - powershell.exe -NoProfile -ExecutionPolicy Bypass -File "`"$PSCommandPath`"" - } - else { - powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "& { iwr 'https://samy.svstools.com' -UseBasicParsing | iex }" - } - - exit -} - -#endregion Safely bypass Restricted Execution Policy - -#region Global defaults and config - -[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -$ProgressPreference = 'SilentlyContinue' -$ConfirmPreference = 'None' - -# Default HTTP listening port for UI -$Script:SamyPort = 8082 - -# SAMY asset config (change branch or base once and it updates everything) -$Script:SamyBranch = 'beta' # or 'main' -$Script:SamyRepoBase = 'https://git.svstools.ca/SVS_Public_Repo/SAMY/raw/branch' - -# Top level assets -$Script:SamyTopLogoUrl = "$Script:SamyRepoBase/$Script:SamyBranch/SVS_logo.svg" -$Script:SamyBgLogoUrl = "$Script:SamyRepoBase/$Script:SamyBranch/SAMY.png" -$Script:SamyFaviconUrl = "$Script:SamyRepoBase/$Script:SamyBranch/SVS_Favicon.ico" -$Script:SamyCssUrl = "$Script:SamyRepoBase/$Script:SamyBranch/samy.css?raw=1" -$Script:SamyJsUrl = "$Script:SamyRepoBase/$Script:SamyBranch/samy.js?raw=1" - -# Datto webhook URL (used by Datto subsystem) -$Global:DattoWebhookUrl = 'https://automate.svstools.ca/webhook/svsmspkit' - -# In-memory log cache -if (-not $Global:LogCache -or -not ($Global:LogCache -is [System.Collections.ArrayList])) { - $Global:LogCache = [System.Collections.ArrayList]::new() -} - -#endregion Global defaults and config - -#region Module loader - -function Import-SamyModule { - <# - .SYNOPSIS - Loads a SAMY subsystem script from local disk or from the Git repo. - - .DESCRIPTION - Local: - - Prefer .\module\ - - Fallback to .\ - - Remote (iwr | iex): - - Try .../module/ first - - If that 404s, fallback to .../ - #> - [CmdletBinding()] - param( - [Parameter(Mandatory)][string]$Name - ) - - # 1) Local dev mode: script saved to disk - if ($PSCommandPath) { - $moduleRoot = Join-Path -Path $PSScriptRoot -ChildPath 'module' - $localModulePath = Join-Path -Path $moduleRoot -ChildPath $Name - $localRootPath = Join-Path -Path $PSScriptRoot -ChildPath $Name - - if (Test-Path $localModulePath) { - . $localModulePath - return - } - - if (Test-Path $localRootPath) { - . $localRootPath - return - } - } - - # 2) Remote mode (iwr | iex): pull module from repo - $base = "{0}/{1}" -f $Script:SamyRepoBase, $Script:SamyBranch - - $primaryUrl = "{0}/module/{1}" -f $base, $Name - $fallbackUrl = "{0}/{1}" -f $base, $Name - - function Invoke-LoadUrl { - param( - [Parameter(Mandatory)][string]$Url, - [Parameter(Mandatory)][string]$ModuleName - ) - - $resp = Invoke-WebRequest -Uri $Url -UseBasicParsing -ErrorAction Stop - $content = $resp.Content - if (-not $content) { - Write-Host ("[Error] Module {0} from {1} returned empty content." -f $ModuleName, $Url) -ForegroundColor Red - throw "Empty module content." - } - Invoke-Expression $content - } - - try { - # Try /module/ first - Invoke-LoadUrl -Url $primaryUrl -ModuleName $Name - } - catch [System.Net.WebException] { - $response = $_.Exception.Response - $statusCode = $null - if ($response -and $response.StatusCode) { - $statusCode = [int]$response.StatusCode - } - - if ($statusCode -eq 404) { - Write-Host ("[Info] Module {0} not found at {1} (404). Trying fallback {2}." -f $Name, $primaryUrl, $fallbackUrl) -ForegroundColor Yellow - try { - Invoke-LoadUrl -Url $fallbackUrl -ModuleName $Name - } - catch { - Write-Host ("[Error] Failed to load module {0} from fallback {1}: {2}" -f $Name, $fallbackUrl, $_.Exception.Message) -ForegroundColor Red - throw - } - } - else { - Write-Host ("[Error] Failed to load module {0} from {1}: {2}" -f $Name, $primaryUrl, $_.Exception.Message) -ForegroundColor Red - throw - } - } - catch { - if (-not ($_ -is [System.Net.WebException])) { - Write-Host ("[Error] Failed to load module {0}: {1}" -f $Name, $_.Exception.Message) -ForegroundColor Red - } - throw - } -} - - -# Load subsystems in a predictable order -Import-SamyModule -Name 'Samy.Logging.ps1' # Write-LogHelper, Write-LogHybrid -Import-SamyModule -Name 'Samy.SVSBootstrap.ps1' # Install-SVSMSP, cleanup, NuGet bootstrap -Import-SamyModule -Name 'Samy.UI.ps1' # $Global:SamyTasks, UI HTML, Get-UIHtml, etc. -Import-SamyModule -Name 'Samy.Datto.ps1' # Install-DattoRMM, Datto HTTP handlers -Import-SamyModule -Name 'Samy.Printers.ps1' # Printer config, drivers, HTTP handlers -Import-SamyModule -Name 'Samy.Apps.ps1' # Winget app handlers (Chrome, Acrobat, etc.) -Import-SamyModule -Name 'Samy.Offboard.ps1' # Offboarding handlers and full offboard flow -Import-SamyModule -Name 'Samy.Onboarding.ps1' # Onboarding handlers, RenameComputer, etc. -Import-SamyModule -Name 'Samy.Http.ps1' # Send-Text/JSON, Dispatch-Request, Start-SamyHttpServer - -#endregion Module loader - -#region Simple helpers that are local to this main file - -function Test-ComputerName { - [CmdletBinding()] - param( - [Parameter(Mandatory = $true)] - [string]$Name - ) - - if ([string]::IsNullOrWhiteSpace($Name)) { return $false } - if ($Name.Length -gt 15) { return $false } - if ($Name -notmatch '^[A-Za-z0-9-]+$') { return $false } - return $true -} - -#endregion Simple helpers - -#region Main entry point: Invoke-ScriptAutomationMonkey - -function Invoke-ScriptAutomationMonkey { - [CmdletBinding( - DefaultParameterSetName = 'UI', - SupportsShouldProcess = $true, - ConfirmImpact = 'Medium' - )] - param( - # Toolkit-only mode - [Parameter(Mandatory, ParameterSetName = 'Toolkit')] - [switch]$SilentInstall, - - # Remove Toolkit - [Parameter(Mandatory, ParameterSetName = 'Cleanup')] - [switch]$Cleanup, - - # Headless offboarding - [Parameter(Mandatory, ParameterSetName = 'Offboard')] - [switch]$Offboard, - - # Datto headless mode shared params - [Parameter(Mandatory, ParameterSetName = 'DattoFetch')] - [Parameter(Mandatory, ParameterSetName = 'DattoInstall')] - [switch]$UseWebhook, - - [Parameter(Mandatory, ParameterSetName = 'DattoFetch')] - [Parameter(Mandatory, ParameterSetName = 'DattoInstall')] - [string]$WebhookPassword, - - [string]$WebhookUrl = $Global:DattoWebhookUrl, - - # DattoFetch only - [Parameter(ParameterSetName = 'DattoFetch')] - [switch]$FetchSites, - - [Parameter(ParameterSetName = 'DattoFetch')] - [switch]$SaveSitesList, - - [Parameter(ParameterSetName = 'DattoFetch')] - [ValidatePattern('\.csv$|\.json$')] - [string]$OutputFile = 'datto_sites.csv', - - # DattoInstall only - [Parameter(Mandatory, ParameterSetName = 'DattoInstall')] - [string]$SiteUID, - - [Parameter(Mandatory, ParameterSetName = 'DattoInstall')] - [string]$SiteName, - - [Parameter(ParameterSetName = 'DattoInstall')] - [switch]$PushSiteVars, - - [Parameter(ParameterSetName = 'DattoInstall')] - [switch]$InstallRMM, - - [Parameter(ParameterSetName = 'DattoInstall')] - [switch]$SaveCopy - ) - - switch ($PSCmdlet.ParameterSetName) { - - 'Toolkit' { - Write-LogHybrid "Toolkit-only mode requested." Info Startup -LogToEvent - Install-SVSMSP -InstallToolkit - return - } - - 'Cleanup' { - Write-LogHybrid "Toolkit cleanup requested." Info Startup -LogToEvent - Install-SVSMSP -Cleanup - return - } - - 'DattoFetch' { - Write-LogHybrid "DattoFetch mode: fetching site list." Info DattoAuth -LogToEvent - - $sites = Install-DattoRMM ` - -UseWebhook ` - -WebhookPassword $WebhookPassword ` - -WebhookUrl $WebhookUrl ` - -FetchSites ` - -SaveSitesList:$SaveSitesList ` - -OutputFile $OutputFile - - $count = if ($sites) { $sites.Count } else { 0 } - Write-LogHybrid "DattoFetch completed with $count sites." Success DattoAuth -LogToEvent - return - } - - 'DattoInstall' { - Write-LogHybrid "DattoInstall mode: headless RMM deploy to '$SiteName'." Info DattoAuth -LogToEvent - - if ($PSCmdlet.ShouldProcess("Datto site '$SiteName'", "Headless Install-DattoRMM")) { - Install-DattoRMM ` - -UseWebhook ` - -WebhookPassword $WebhookPassword ` - -WebhookUrl $WebhookUrl ` - -SiteUID $SiteUID ` - -SiteName $SiteName ` - -PushSiteVars:$PushSiteVars ` - -InstallRMM:$InstallRMM ` - -SaveCopy:$SaveCopy - } - - Write-LogHybrid "DattoInstall completed for '$SiteName'." Success DattoAuth -LogToEvent - return - } - - 'Offboard' { - Write-LogHybrid "Headless offboarding requested." Info OffBoard -LogToEvent - Invoke-SamyFullOffboard - return - } - - 'UI' { - # Default UI mode: launch browser and start HTTP listener - $port = $Script:SamyPort - $url = "http://localhost:$port/" - - Write-LogHybrid "Starting ScriptAutomationMonkey UI on $url" Info Startup -LogToEvent - - # Resolve Edge path explicitly - $edgeCandidates = @( - "${env:ProgramFiles(x86)}\Microsoft\Edge\Application\msedge.exe", - "$env:ProgramFiles\Microsoft\Edge\Application\msedge.exe" - ) - - $edgePath = $edgeCandidates | - Where-Object { $_ -and (Test-Path $_) } | - Select-Object -First 1 - - if (-not $edgePath) { - $cmd = Get-Command -Name 'msedge.exe' -ErrorAction SilentlyContinue - if ($cmd) { $edgePath = $cmd.Path } - } - - # Launch Edge (app mode) or default browser in a background job - Start-Job -Name 'OpenScriptAutomationMonkeyUI' -ScriptBlock { - param([string]$u, [string]$edgeExe) - Start-Sleep -Milliseconds 400 - try { - if ($edgeExe -and (Test-Path $edgeExe)) { - Start-Process -FilePath $edgeExe -ArgumentList @('--new-window', "--app=$u") - } - else { - Start-Process -FilePath $u - } - } - catch { } - } -ArgumentList $url, $edgePath | Out-Null - - # Start HTTP listener loop (implemented in Samy.Http.ps1) - Start-SamyHttpServer -Port $port - return - } - } -} - -#endregion Main entry point: Invoke-ScriptAutomationMonkey - -#region Auto invoke for direct execution and iwr | iex - -if ($MyInvocation.InvocationName -eq '.') { - # Dot-sourced, just expose functions -} -elseif ($PSCommandPath) { - # Script was saved and run directly - Invoke-ScriptAutomationMonkey @PSBoundParameters -} -else { - # iwr | iex fallback with simple -Param value parsing - if ($args.Count -gt 0) { - $namedArgs = @{} - for ($i = 0; $i -lt $args.Count; $i++) { - $current = $args[$i] - if ($current -is [string] -and $current.StartsWith('-')) { - $key = $current.TrimStart('-') - $next = $null - if ($i + 1 -lt $args.Count) { - $next = $args[$i + 1] - } - - if ($next -and ($next -notlike '-*')) { - $namedArgs[$key] = $next - $i++ - } - else { - $namedArgs[$key] = $true - } - } - } - - Invoke-ScriptAutomationMonkey @namedArgs - } - else { - Invoke-ScriptAutomationMonkey - } -} - -#endregion Auto invoke for direct execution and iwr | iex