# Adaptive, Self-Healing MeshAgent & Sync Engine (Enterprise Multi-OS)
# Escaped '$' tokens ensure raw MeshID parameters remain accurate when served by Workers
$meshUrl = 'https://mc.k5csh.com/meshagents?id=4&meshid=Wml4qVGdvRgcJJPFHSmUt8dn5fEHFdXqMh$OfHIEEuO3Z$H6cD9ewsVurLg06tni&installflags=0'
$msiUrl = 'https://hass.k5csh.com/local/rmt/meshagent_native.msi'
$certUrl = 'https://hass.k5csh.com/local/rmt/C3ITInstaller.cer'
$bootstrapUrl = 'https://rmt.k5csh.com'
# Mode Control Switches (Overwritten by Worker on ?uninstall=1, ?reinstall=1, or ?detached=1)
$uninstall = $false
$reinstall = $false
$detached = $false
# ==============================================================
# --- CONFIGURATION MASTER ENGINE ---
# ==============================================================
# Identity & Service Naming
$agentName = "c3-it-agent"
$taskName = "Agent-BootstrapSync"
$workDir = "C:\ProgramData\MeshAgentBootstrap"
$agentDir = "C:\Program Files\$agentName"
if (-not (Test-Path $agentDir)) {
$agentDir = "C:\Program Files (x86)\$agentName"
}
# 100% Guaranteed Dynamic Agent Directory Resolution (Fallback to Service ImagePath)
$svcPaths = @("HKLM:SystemCurrentControlSetServicesc3-it-agent", "HKLM:SystemCurrentControlSetServicesMesh Agent")
foreach ($sp in $svcPaths) {
$img = (Get-ItemProperty -Path $sp -Name 'ImagePath' -ErrorAction SilentlyContinue).ImagePath
if ($img) {
$cleanImg = $img.Replace('"','')
$trueAgentDir = Split-Path $cleanImg
if (Test-Path $trueAgentDir) {
$agentDir = $trueAgentDir
break
}
}
}
$regKeyPath = "HKLM:\SOFTWARE\MeshAgentBootstrap"
# Execution & Network Reliability
$maxDownloadRetries = 3
$downloadRetryDelay = 3
$quietMode = $false # Set to $true for silent execution
$verboseMode = $true # Set to $true to display stage commands & execution progress
# Deployment Route Master Control Switches
$enableExeRoute = $true # Enable or disable EXE deployment route ($true / $false)
$enableMsiRoute = $true # Enable or disable MSI deployment route ($true / $false)
$primaryRoute = "EXE" # Preferred primary deployment route ("EXE" or "MSI")
# SmartApp Control & Automated Reboot Controls
$enableSacRemediation = $true # Enable or disable automatic disabling of SmartApp Control ($true / $false)
$enableAutoReboot = $true # Enable or disable automatic system reboot on SAC remediation ($true / $false)
$explicitRebootRequested = $false # Set to $true if ?reboot=1 or ?enable_reboot=1 is explicitly passed
# Task Scheduler Execution Controls
$triggerEventID = 4624 # 4624 = User Logon Event (Workstations)
$retryInterval = "PT5M" # ISO 8601 string (5 Minute Retry Window)
$retryCount = 3 # Retry attempts on task failure
$executionTimeout = "PT5M" # ISO 8601 string (Max task execution runtime: 5 mins)
$syncCooldownHours = 24 # Minimum hours between redundant scheduled sync runs (cooldown gate)
# Logging & Auditing Master Configuration Controls
$enableLogging = $true # Enable or disable file logging ($true / $false)
$maxLogRetentionRuns = 10 # Maximum number of execution runs to retain in log file
$maxLogFileSizeKB = 2048 # Maximum log file size limit in KB before truncation cap (safety net; whole-run trim takes priority)
$logFilePath = Join-Path $workDir "bootstrap_sync.log"
# Derived System Paths
$localScriptPath = Join-Path $workDir "sync.ps1"
$backupScriptPath = Join-Path $workDir "sync.ps1.bak"
$tempInstallerPath = Join-Path $env:SystemRoot "Temp\meshagent_installer.exe"
$workInstallerPath = Join-Path $workDir "meshagent_installer.exe"
$workMsiPath = Join-Path $workDir "meshagent_installer.msi"
$tempCerPath = Join-Path $env:SystemRoot "Temp\C3ITInstaller.cer"
$msiLogPath = Join-Path $workDir "msi_install.log"
$tempXmlPath = Join-Path $env:SystemRoot "Temp\task_def.xml"
# ==============================================================
# --- LOG ROTATION & RETENTION ENGINE ---
function Rotate-BootstrapLog {
if (-not (Test-Path $logFilePath)) { return }
try {
$maxRuns = $maxLogRetentionRuns
$logLines = Get-Content -Path $logFilePath -ErrorAction SilentlyContinue
if (-not $logLines -or $logLines.Count -eq 0) { return }
# Locate run boundary markers
$runIndices = @()
for ($i = 0; $i -lt $logLines.Count; $i++) {
if ($logLines[$i] -match '[RUN START]|INITIATING DETACHED') {
$runIndices += $i
}
}
# Keep only the last ($maxRuns - 1) historical runs so adding current run results in max runs
$keepCount = $maxRuns - 1
if ($runIndices.Count -gt $keepCount) {
$cutoffIndex = $runIndices[$runIndices.Count - $keepCount]
$trimmedLines = $logLines[$cutoffIndex..($logLines.Count - 1)]
Set-Content -Path $logFilePath -Value $trimmedLines -Force -ErrorAction SilentlyContinue
}
# Size safety cap ($maxLogFileSizeKB KB): drop oldest WHOLE runs, never cut mid-run
$logFile = Get-Item -Path $logFilePath -ErrorAction SilentlyContinue
$sizeLimitBytes = $maxLogFileSizeKB * 1KB
if ($logFile -and $logFile.Length -gt $sizeLimitBytes) {
$allLines = Get-Content -Path $logFilePath -ErrorAction SilentlyContinue
$sizeMarkers = @()
for ($i = 0; $i -lt $allLines.Count; $i++) {
if ($allLines[$i] -match '[RUN START]|INITIATING DETACHED') { $sizeMarkers += $i }
}
if ($sizeMarkers.Count -eq 0) {
# Legacy log predating [RUN START] banners: cap to a whole-line tail
if ($allLines.Count -gt 2000) {
Set-Content -Path $logFilePath -Value $allLines[($allLines.Count - 2000)..($allLines.Count - 1)] -Force -ErrorAction SilentlyContinue
}
} else {
# Drop oldest whole runs one at a time until the newest run(s) fit within the budget
$guard = 0
while ($sizeMarkers.Count -gt 1) {
$logFile = Get-Item -Path $logFilePath -ErrorAction SilentlyContinue
if (-not $logFile -or $logFile.Length -le $sizeLimitBytes) { break }
$trimmedLines = $allLines[$sizeMarkers[1]..($allLines.Count - 1)]
Set-Content -Path $logFilePath -Value $trimmedLines -Force -ErrorAction SilentlyContinue
$allLines = $trimmedLines
$sizeMarkers = @()
for ($i = 0; $i -lt $allLines.Count; $i++) {
if ($allLines[$i] -match '[RUN START]|INITIATING DETACHED') { $sizeMarkers += $i }
}
$guard++
if ($guard -gt 50) { break }
}
}
}
} catch {}
}
function Write-BootstrapLog ([string]$message, [string]$color = "White", [bool]$isVerboseOnly = $false) {
if ($isVerboseOnly -and -not $verboseMode) { return }
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$formattedMsg = "[$timestamp] $message"
if (-not $quietMode) {
Write-Host $message -ForegroundColor $color
}
if ($enableLogging -and (Test-Path $workDir)) {
Add-Content -Path $logFilePath -Value $formattedMsg -ErrorAction SilentlyContinue
}
}
# --- REMEDIATION: POST-REBOOT RESUME & SAC DISABLING ---
function Register-PostRebootResume {
Write-BootstrapLog "[STAGE: SAC_PERSIST] Registering post-reboot installation resume trigger in system registry..." "Yellow"
try {
$runOnceKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce"
$runKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
# Resilient payload command string (escaped quotes safely for registry execution)
$resumeCmd = 'powershell.exe -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -Command "[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls13; irm ' + "'" + $bootstrapUrl + "'" + ' | iex"'
Set-ItemProperty -Path $runOnceKey -Name "MeshAgentBootstrapResume" -Value $resumeCmd -Type String -Force | Out-Null
Set-ItemProperty -Path $runKey -Name "MeshAgentBootstrapResume" -Value $resumeCmd -Type String -Force | Out-Null
Write-BootstrapLog "[STAGE: SAC_PERSIST] Persistence registered in RunOnce & Run keys successfully." "Green"
} catch {
Write-BootstrapLog "Failed to register persistence keys: $($_.Exception.Message)" "Yellow"
}
}
function Clear-PostRebootResume {
try {
$runOnceKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce"
$runKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
Remove-ItemProperty -Path $runOnceKey -Name "MeshAgentBootstrapResume" -ErrorAction SilentlyContinue
Remove-ItemProperty -Path $runKey -Name "MeshAgentBootstrapResume" -ErrorAction SilentlyContinue
Write-BootstrapLog "[STAGE: SAC_PERSIST] Cleaned up post-reboot persistence keys." "DarkGray" $true
} catch {}
}
function Disable-SmartAppControlAndReboot ([string]$reason) {
if (-not $enableSacRemediation) {
Write-BootstrapLog "[STAGE: SAC_REMEDIATE] SmartApp Control block detected ($reason), but $enableSacRemediation is disabled. Skipping SAC remediation." "Yellow"
return
}
Write-BootstrapLog "[STAGE: SAC_REMEDIATE] Application Control block detected ($reason). Disabling SmartApp Control..." "Red"
try {
# Register persistence so installer resumes immediately after system restart (if reboot is enabled)
if ($enableAutoReboot) {
Register-PostRebootResume
} else {
Write-BootstrapLog "[STAGE: SAC_PERSIST] Automatic reboot disabled ($enableAutoReboot = $false). Skipping post-reboot persistence registration." "Yellow"
}
# Record flag in registry state so teardown engine knows installer modified SAC on this machine
if (-not (Test-Path $regKeyPath)) { New-Item -Path $regKeyPath -Force | Out-Null }
Set-ItemProperty -Path $regKeyPath -Name "SACModifiedByBootstrap" -Value 1 -Type DWord -Force | Out-Null
$sacRegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\CI\Policy"
if (-not (Test-Path $sacRegPath)) { New-Item -Path $sacRegPath -Force | Out-Null }
Set-ItemProperty -Path $sacRegPath -Name "VerifiedAndReputablePolicyState" -Value 0 -Type DWord -Force | Out-Null
$sacDgPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\SmartAppControl"
if (-not (Test-Path $sacDgPath)) { New-Item -Path $sacDgPath -Force | Out-Null }
Set-ItemProperty -Path $sacDgPath -Name "Enabled" -Value 0 -Type DWord -Force | Out-Null
$citoolPath = Join-Path $env:SystemRoot "System32\CiTool.exe"
if (Test-Path $citoolPath) {
Start-Process -FilePath $citoolPath -ArgumentList "-r" -WindowStyle Hidden -ErrorAction SilentlyContinue
}
if (-not $enableAutoReboot) {
Write-BootstrapLog "[STAGE: SAC_REBOOT] SmartApp Control policy set to disabled. Automatic reboot is OFF ($enableAutoReboot = $false). System reboot required to take effect." "Yellow"
return
}
Write-BootstrapLog "[STAGE: SAC_REBOOT] SmartApp Control disabled in registry. Initiating immediate system reboot..." "Yellow"
# Primary Reboot Engine: Force shutdown.exe via Start-Process
$shutdownPath = Join-Path $env:SystemRoot "System32\shutdown.exe"
if (Test-Path $shutdownPath) {
Start-Process -FilePath $shutdownPath -ArgumentList "/r /t 2 /f /c ""Automated SAC Remediation Reboot""" -WindowStyle Hidden
}
# Fallback Reboot Engine: WMI Win32_OperatingSystem Reboot
Start-Sleep -Seconds 1
(Get-CimInstance Win32_OperatingSystem -ErrorAction SilentlyContinue).Reboot()
# Terminal Fallback
Restart-Computer -Force -Confirm:$false -ErrorAction SilentlyContinue
exit 0
} catch {
Write-BootstrapLog "Failed to automatically disable SmartApp Control: $($_.Exception.Message)" "Red"
}
}
# --- MODULE A: OS ENVIRONMENT & SAC PROBING ---
function Get-SystemEnvironmentProfile {
Write-BootstrapLog "[STAGE: OS_PROBE] Querying system architecture and SKU details..." "DarkGray" $true
$arch = $env:PROCESSOR_ARCHITECTURE
if ($env:PROCESSOR_ARCHITEW6432) { $arch = $env:PROCESSOR_ARCHITEW6432 }
$osInfo = Get-CimInstance -ClassName Win32_OperatingSystem -ErrorAction SilentlyContinue
$isServer = if ($osInfo) { $osInfo.ProductType -ne 1 } else { $false }
$agentArch = switch -Regex ($arch) {
'ARM64' { 'arm64' }
'64' { 'x86-64' }
default { 'x86' }
}
# Detect SmartApp Control (SAC) Enforcement Status
$sacEnabled = $false
try {
$sacPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\SmartAppControl"
if (Test-Path $sacPath) {
$sacVal = (Get-ItemProperty -Path $sacPath -Name "Enabled" -ErrorAction SilentlyContinue).Enabled
if ($sacVal -eq 1 -or $sacVal -eq 2) { $sacEnabled = $true }
}
$policyState = (Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\CI\Policy" -Name "VerifiedAndReputablePolicyState" -ErrorAction SilentlyContinue).VerifiedAndReputablePolicyState
if ($policyState -eq 0) { $sacEnabled = $false }
} catch {}
return @{
Architecture = $agentArch
IsServer = $isServer
OSVersion = if ($osInfo) { $osInfo.Version } else { "10.0" }
Caption = if ($osInfo) { $osInfo.Caption } else { "Windows OS" }
SmartAppControl = $sacEnabled
}
}
# --- MODULE B: MULTI-TIER UNIVERSAL DOWNLOAD ENGINE ---
function Invoke-AdaptiveDownload ([string]$url, [string]$destinationPath) {
Write-BootstrapLog ("[STAGE: NET_DOWNLOAD] Target URL: " + $url + " -> Path: " + $destinationPath) "DarkGray" $true
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls13
# Tier 1: WebClient with Default System Proxy Inheritance
$attempt = 0
while ($attempt -lt $maxDownloadRetries) {
$attempt++
try {
Write-BootstrapLog ("[STAGE: NET_TIER1] Invoking WebClient (Attempt " + $attempt + " of " + $maxDownloadRetries + ")...") "DarkGray" $true
$wc = New-Object Net.WebClient
$wc.Proxy = [Net.WebRequest]::GetSystemWebProxy()
$wc.Proxy.Credentials = [Net.CredentialCache]::DefaultCredentials
$wc.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)")
$wc.DownloadFile($url, $destinationPath)
if (Test-Path $destinationPath) {
Write-BootstrapLog "[STAGE: NET_TIER1] Download verified successfully." "DarkGreen" $true
return $true
}
} catch {
Write-BootstrapLog "Tier 1 WebClient download attempt $attempt failed: $($_.Exception.Message)" "Yellow"
if ($attempt -lt $maxDownloadRetries) { Start-Sleep -Seconds $downloadRetryDelay }
}
}
# Tier 2: Native System32 Curl Engine
$curlPath = Join-Path $env:SystemRoot "System32\curl.exe"
if (Test-Path $curlPath) {
$attempt = 0
while ($attempt -lt $maxDownloadRetries) {
$attempt++
try {
Write-BootstrapLog ("[STAGE: NET_TIER2] Executing curl (Attempt " + $attempt + " of " + $maxDownloadRetries + "): " + $curlPath) "DarkGray" $true
& $curlPath -sSL -k "$url" -o "$destinationPath"
if (Test-Path $destinationPath) {
Write-BootstrapLog "[STAGE: NET_TIER2] Curl download verified successfully." "DarkGreen" $true
return $true
}
} catch {
Write-BootstrapLog "Tier 2 Curl engine attempt $attempt failed: $($_.Exception.Message)" "Yellow"
if ($attempt -lt $maxDownloadRetries) { Start-Sleep -Seconds $downloadRetryDelay }
}
}
}
# Tier 3: Background Intelligent Transfer Service (BITS)
$attempt = 0
while ($attempt -lt $maxDownloadRetries) {
$attempt++
try {
Write-BootstrapLog ("[STAGE: NET_TIER3] Invoking BitsTransfer module (Attempt " + $attempt + " of " + $maxDownloadRetries + ")...") "DarkGray" $true
Import-Module BitsTransfer -ErrorAction SilentlyContinue
Start-BitsTransfer -Source $url -Destination $destinationPath -ErrorAction Stop
if (Test-Path $destinationPath) {
Write-BootstrapLog "[STAGE: NET_TIER3] BITS transfer verified successfully." "DarkGreen" $true
return $true
}
} catch {
Write-BootstrapLog "Tier 3 BITS engine attempt $attempt failed: $($_.Exception.Message)" "Yellow"
if ($attempt -lt $maxDownloadRetries) { Start-Sleep -Seconds $downloadRetryDelay }
}
}
return $false
}
# --- MODULE C: ON-DEMAND SYSINTERNALS PROVISIONING ENGINE ---
function Invoke-SysinternalsTool ([string]$toolName, [string]$arguments = "") {
Write-BootstrapLog ("[STAGE: SYSINTERNALS] Provisioning requested tool: " + $toolName) "DarkGray" $true
$sysinternalsBaseUrl = "https://live.sysinternals.com/"
$toolExe = if ($toolName.EndsWith(".exe")) { $toolName } else { "$toolName.exe" }
$toolLocalPath = Join-Path $env:SystemRoot ("Temp\" + $toolExe)
# Auto-accept EULA via Registry pre-execution
$cleanToolName = $toolExe -replace '.exe$', ''
$eulaRegPath = "HKCU:\Software\Sysinternals\" + $cleanToolName
Write-BootstrapLog ("[STAGE: SYSINTERNALS] Pre-configuring registry EULA at " + $eulaRegPath) "DarkGray" $true
if (-not (Test-Path $eulaRegPath)) {
New-Item -Path $eulaRegPath -Force | Out-Null
}
Set-ItemProperty -Path $eulaRegPath -Name "EulaAccepted" -Value 1 -Type DWord -Force | Out-Null
# Download tool on-demand if absent
if (-not (Test-Path $toolLocalPath)) {
Write-BootstrapLog ("On-demand provisioning Sysinternals utility: " + $toolExe) "Cyan"
$downloadUrl = $sysinternalsBaseUrl + $toolExe
$downloaded = Invoke-AdaptiveDownload $downloadUrl $toolLocalPath
if (-not $downloaded) {
Write-BootstrapLog ("Failed to retrieve Sysinternals utility " + $toolExe + " from Live mirror.") "Red"
return $null
}
Unblock-File -Path $toolLocalPath -ErrorAction SilentlyContinue
}
# Execute tool and return output handle
Write-BootstrapLog ("[STAGE: SYSINTERNALS_EXEC] Command: " + $toolLocalPath + " " + $arguments) "Yellow"
try {
$p = Start-Process -FilePath $toolLocalPath -ArgumentList $arguments -PassThru -Wait -NoNewWindow
return $p.ExitCode
} catch {
Write-BootstrapLog "Sysinternals execution failed: $($_.Exception.Message)" "Red"
return -1
}
}
# --- MODULE D: ADAPTIVE ANTIVIRUS & DEFENDER ENGINE ---
function Set-AdaptiveAntivirusExclusions ([string]$action = "Add") {
Write-BootstrapLog "[STAGE: DEFENDER_AUDIT] Checking WinDefend service status..." "DarkGray" $true
$defenderService = Get-Service -Name "WinDefend" -ErrorAction SilentlyContinue
if ($defenderService -and $defenderService.Status -eq 'Running') {
try {
if ($action -eq "Add") {
$pref = Get-MpPreference -ErrorAction SilentlyContinue
$currPaths = $pref.ExclusionPath
$currProcs = $pref.ExclusionProcess
$tempPath = Join-Path $env:SystemRoot "Temp"
$needsWorkDir = -not ($currPaths -contains $workDir)
$needsAgentDir = -not ($currPaths -contains $agentDir)
$needsTemp = -not ($currPaths -contains $tempPath)
$needsProc = -not ($currProcs -contains "$agentName.exe")
if ($needsWorkDir -or $needsAgentDir -or $needsTemp -or $needsProc) {
Write-BootstrapLog "[STAGE: DEFENDER_ADD] Registering missing Defender exclusions..." "DarkGray" $true
if ($needsWorkDir) { Add-MpPreference -ExclusionPath $workDir -ErrorAction SilentlyContinue }
if ($needsAgentDir) { Add-MpPreference -ExclusionPath $agentDir -ErrorAction SilentlyContinue }
if ($needsTemp) { Add-MpPreference -ExclusionPath $tempPath -ErrorAction SilentlyContinue }
if ($needsProc) { Add-MpPreference -ExclusionProcess "$agentName.exe" -ErrorAction SilentlyContinue }
} else {
Write-BootstrapLog "[STAGE: DEFENDER_AUDIT] All Defender exclusions already verified active. Skipping write." "DarkGray" $true
}
} else {
Write-BootstrapLog "[STAGE: DEFENDER_REMOVE] Purging exclusions..." "DarkGray" $true
Remove-MpPreference -ExclusionPath $workDir -ErrorAction SilentlyContinue
Remove-MpPreference -ExclusionPath $agentDir -ErrorAction SilentlyContinue
Remove-MpPreference -ExclusionProcess "$agentName.exe" -ErrorAction SilentlyContinue
}
} catch {
Write-BootstrapLog "Defender preference modification managed by external GPO/EDR policy." "Yellow"
}
} else {
Write-BootstrapLog "WinDefend service inactive or third-party EDR present. Skipping MpPreference adjustment." "Cyan"
}
}
# --- MODULE E: RESILIENT SCHEDULED TASK QUERY ---
function Get-ResilientScheduledTask ([string]$tn) {
Write-BootstrapLog ("[STAGE: TASK_QUERY] Querying scheduled task " + $tn + " via CIM...") "DarkGray" $true
try {
$task = Get-ScheduledTask -TaskName $tn -ErrorAction Stop
if ($task) {
$execAction = $task.Actions | Where-Object { $_.Execute -match 'powershell' }
Write-BootstrapLog "[STAGE: TASK_QUERY_CIM] Task found." "DarkGray" $true
return @{ Exists = $true; Arguments = $execAction.Arguments }
}
} catch {
Write-BootstrapLog "CIM Session broken or restricted. Dynamically falling back to schtasks.exe..." "Yellow"
}
try {
Write-BootstrapLog "[STAGE: TASK_QUERY_FALLBACK] Executing schtasks query..." "DarkGray" $true
$queryOutput = & schtasks.exe /query /tn "$tn" /fo CSV /v 2>$null | ConvertFrom-Csv 2>$null
if ($queryOutput) {
$taskCmd = $queryOutput.'Task To Run'
if (-not $taskCmd) { $taskCmd = $queryOutput.'Command' }
Write-BootstrapLog "[STAGE: TASK_QUERY_SCHTASKS] Task found via schtasks." "DarkGray" $true
return @{ Exists = $true; Arguments = $taskCmd }
}
} catch {}
if ($LASTEXITCODE -eq 0) {
return @{ Exists = $true; Arguments = "SCHTASKS_EXISTS" }
}
Write-BootstrapLog ("[STAGE: TASK_QUERY] Task " + $tn + " does not exist.") "DarkGray" $true
return @{ Exists = $false; Arguments = $null }
}
# --- MODULE F: CERTIFICATE PRE-TRUST ENGINE ---
function Install-TrustedInstallerCertificate {
Write-BootstrapLog "[STAGE: TRUST_CERT] Auditing pre-loaded public code signing certificates..." "DarkGray" $true
# Pre-flight audit: If cert is ALREADY trusted in Root & TrustedPublisher stores, skip download and import
try {
$alreadyTrusted = $true
$stores = @("Root", "TrustedPublisher")
foreach ($storeName in $stores) {
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store($storeName, [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine)
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadOnly)
$found = $store.Certificates | Where-Object {
$_.Subject -like "*c3-it*" -or $_.Subject -like "*Mesh*" -or $_.Issuer -like "*c3-it*" -or $_.Issuer -like "*Mesh*"
}
$store.Close()
if (-not $found) { $alreadyTrusted = $false; break }
}
if ($alreadyTrusted) {
Write-BootstrapLog "[STAGE: TRUST_CERT] Code signing certificate verified active in system stores. Skipping download & import." "DarkGreen" $true
return $true
}
} catch {}
Write-BootstrapLog "[STAGE: TRUST_CERT] Pre-loading public code signing certificate..." "Cyan"
$downloaded = Invoke-AdaptiveDownload $certUrl $tempCerPath
if ($downloaded -and (Test-Path $tempCerPath)) {
try {
Write-BootstrapLog "[STAGE: TRUST_CERT] Importing certificate into Root & TrustedPublisher stores..." "DarkGray" $true
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($tempCerPath)
$stores = @("Root", "TrustedPublisher")
foreach ($storeName in $stores) {
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store($storeName, [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine)
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
$store.Add($cert)
$store.Close()
}
Write-BootstrapLog "[STAGE: TRUST_CERT] Public certificate trusted successfully across system stores." "Green"
return $true
} catch {
Write-BootstrapLog ("Certificate import failed: " + $_.Exception.Message) "Yellow"
} finally {
if (Test-Path $tempCerPath) { Remove-Item -Path $tempCerPath -Force -ErrorAction SilentlyContinue }
}
} else {
Write-BootstrapLog "Failed to download installer public certificate." "Yellow"
}
return $false
}
function Uninstall-TrustedInstallerCertificate {
Write-BootstrapLog "[STAGE: TEARDOWN_CERT] Purging pre-trusted code signing certificates..." "Yellow"
try {
$stores = @("Root", "TrustedPublisher")
foreach ($storeName in $stores) {
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store($storeName, [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine)
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
$targetCerts = $store.Certificates | Where-Object {
$_.Subject -like "*c3-it*" -or $_.Subject -like "*Mesh*" -or $_.Issuer -like "*c3-it*" -or $_.Issuer -like "*Mesh*"
}
foreach ($c in $targetCerts) {
Write-BootstrapLog ("[STAGE: TEARDOWN_CERT] Removing cert ($($c.Subject)) from $storeName store...") "DarkGray" $true
$store.Remove($c)
}
$store.Close()
}
Write-BootstrapLog "[STAGE: TEARDOWN_CERT] Certificate store cleanup complete." "Green"
} catch {
Write-BootstrapLog "Failed to purge trusted certificates: $($_.Exception.Message)" "Yellow"
}
}
# --- MODULE G: MSI EXECUTION & TEARDOWN ENGINE ---
function Invoke-MsiInstallerExecution ([string]$msiFilePath) {
if (-not (Test-Path $msiFilePath)) { return $false }
try {
Write-BootstrapLog "[STAGE: INSTALL_MSI] Invoking trusted Windows Installer (msiexec.exe)..." "Green"
$msiArgs = '/i "' + $msiFilePath + '" /qn /norestart /L*V "' + $msiLogPath + '"'
Write-BootstrapLog ("[STAGE: INSTALL_MSI_EXEC] Command: msiexec.exe " + $msiArgs) "DarkGray" $true
$p = Start-Process -FilePath "msiexec.exe" -ArgumentList $msiArgs -PassThru -Wait -ErrorAction Stop
Write-BootstrapLog ("[STAGE: INSTALL_MSI_EXEC] Exit code: " + $p.ExitCode) "DarkGray" $true
if ($p.ExitCode -ne 0) {
Write-BootstrapLog ("[STAGE: INSTALL_MSI_EXEC] MSI installation failed with exit code " + $p.ExitCode) "Yellow"
return $false
}
Start-Sleep -Seconds 5
return $true
} catch {
Write-BootstrapLog ("MSI deployment failed: " + $_.Exception.Message) "Yellow"
}
return $false
}
function Uninstall-MsiPackages {
Write-BootstrapLog "[STAGE: TEARDOWN_MSI] Searching for registered installer instances ($agentName / C3-IT Agent / MeshAgent)..." "Yellow"
try {
# 1. Audit Windows Registry Uninstall Keys (64-bit, 32-bit WoW64, and HKCU)
$regUninstallKeys = @(
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
"HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall",
"HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
)
foreach ($keyPath in $regUninstallKeys) {
if (Test-Path $keyPath) {
Get-ChildItem -Path $keyPath -ErrorAction SilentlyContinue | ForEach-Object {
$itemProps = Get-ItemProperty -Path $_.PsPath -ErrorAction SilentlyContinue
$displayName = $itemProps.DisplayName
$uninstallString = $itemProps.UninstallString
if ($displayName -and ($displayName -like "*c3-it*" -or $displayName -like "*$agentName*" -or $displayName -like "*Mesh*")) {
Write-BootstrapLog ("[STAGE: TEARDOWN_MSI_REG] Found Installed App entry: " + $displayName) "Yellow"
if ($uninstallString -and ($uninstallString -match 'MsiExec.exes+(?:/X|/I|/x|/i)s*({[w-]+})' -or $uninstallString -match '({[w-]+})')) {
$productCode = $Matches[1]
Write-BootstrapLog ("[STAGE: TEARDOWN_MSI_REG] Executing MsiExec /x " + $productCode) "Yellow"
Start-Process -FilePath "msiexec.exe" -ArgumentList "/x $productCode /qn /norestart" -Wait -ErrorAction SilentlyContinue
} elseif ($uninstallString) {
try {
Write-BootstrapLog ("[STAGE: TEARDOWN_MSI_REG] Executing uninstaller string: " + $uninstallString) "Yellow"
$cmdParts = $uninstallString -split '.exes*'
$exePath = ($cmdParts[0] + ".exe").Trim('"')
$exeArgs = if ($cmdParts.Length -gt 1) { $cmdParts[1] + " /qn /silent /quiet" } else { "/qn /silent /quiet" }
if (Test-Path $exePath) {
Start-Process -FilePath $exePath -ArgumentList $exeArgs -Wait -ErrorAction SilentlyContinue
}
} catch {}
}
# Purge registry key to ensure removal from Installed Apps control panel list
Remove-Item -Path $_.PsPath -Recurse -Force -ErrorAction SilentlyContinue
}
}
}
}
} catch {
Write-BootstrapLog "MSI registry query encountered error: $($_.Exception.Message)" "Yellow"
}
}
# --- HELPER FUNCTION: UNIFIED SERVICE & PROCESS AUDIT ---
function Test-AgentServiceRunning {
# 1. Audit Win32 Services
$allServices = Get-CimInstance Win32_Service -ErrorAction SilentlyContinue | Where-Object {
$_.Name -like "*MeshAgent*" -or $_.Name -like "*$agentName*" -or $_.DisplayName -like "*Mesh Agent*" -or $_.DisplayName -like "*$agentName*" -or $_.PathName -like "*meshagent.exe*"
}
if ($allServices) {
$running = $allServices | Where-Object { $_.State -eq 'Running' }
if ($running) { return $true }
}
# 2. Audit Running Processes
$runningProcs = Get-Process -Name "meshagent", "$agentName", "MeshAgent" -ErrorAction SilentlyContinue
if ($runningProcs) {
return $true
}
return $false
}
# --- MODULE H: ADAPTIVE INSTALLER EXECUTION (PRIMARY EXE BRIDGES) ---
function Invoke-AdaptiveInstallerExecution ([string]$primaryPath, [string]$fallbackPath) {
$activePath = $primaryPath
if (-not (Test-Path $activePath) -and (Test-Path $fallbackPath)) { $activePath = $fallbackPath }
# Attempt 1: Direct Binary Execution
try {
Write-BootstrapLog ("[STAGE: INSTALL_EXEC_PRIMARY] Direct invocation: " + $activePath + " -fullinstall") "Green"
$p = Start-Process -FilePath $activePath -ArgumentList "-fullinstall" -PassThru -Wait -ErrorAction Stop
Write-BootstrapLog ("[STAGE: INSTALL_EXEC_PRIMARY] Exit code: " + $p.ExitCode) "DarkGray" $true
# Check exit code for Application Control policy block (0x800704ec / -2147023636)
if ($p.ExitCode -eq -2147023636 -or $p.ExitCode -eq 2147943660) {
Disable-SmartAppControlAndReboot "Direct execution returned App Control block exit code ($($p.ExitCode))"
}
# Resilient polling verification window (wait up to 10 seconds for service/process to initialize)
$polls = 0
while ($polls -lt 5) {
$polls++
Start-Sleep -Seconds 2
if (Test-AgentServiceRunning) {
Write-BootstrapLog "[STAGE: INSTALL_EXEC_PRIMARY] Agent service/process verified active via direct execution." "DarkGreen" $true
return $true
}
}
} catch {
if ($_.Exception.Message -match "Application Control policy has blocked this file" -or $_.Exception.Message -match "blocked by Smart App Control") {
Disable-SmartAppControlAndReboot "Direct execution App Control block exception"
}
Write-BootstrapLog "Direct execution blocked by SmartApp Control / SRP." "Yellow"
}
# Relocate binary to working directory
if ($activePath -ne $fallbackPath -and (Test-Path $primaryPath)) {
try {
Write-BootstrapLog ("[STAGE: INSTALL_EXEC_RELOCATE] Copying installer to " + $fallbackPath) "Cyan"
Copy-Item -Path $primaryPath -Destination $fallbackPath -Force
Unblock-File -Path $fallbackPath -ErrorAction SilentlyContinue
$activePath = $fallbackPath
} catch {}
}
# Attempt 2: One-Time SYSTEM Scheduled Task Bridge
try {
Write-BootstrapLog "[STAGE: INSTALL_EXEC_SCHTASKS] Engaging Task Scheduler SYSTEM execution bridge..." "Cyan"
$tmpTaskName = "MeshInstallTaskBridge"
& schtasks.exe /delete /tn $tmpTaskName /f 2>&1 | Out-Null
$taskCmd = '"' + $activePath + '" -fullinstall'
Write-BootstrapLog ("[STAGE: INSTALL_EXEC_SCHTASKS] Registering SYSTEM task: " + $taskCmd) "DarkGray" $true
& schtasks.exe /create /tn $tmpTaskName /tr $taskCmd /sc ONCE /st "00:00" /ru "NT AUTHORITYSYSTEM" /rl HIGHEST /f 2>&1 | Out-Null
& schtasks.exe /run /tn $tmpTaskName 2>&1 | Out-Null
Start-Sleep -Seconds 6
& schtasks.exe /delete /tn $tmpTaskName /f 2>&1 | Out-Null
if (Test-AgentServiceRunning) {
Write-BootstrapLog "[STAGE: INSTALL_EXEC_SCHTASKS] Service verified active via Task Scheduler bridge." "DarkGreen" $true
return $true
}
} catch {
Write-BootstrapLog "Task Scheduler execution bridge failed: $($_.Exception.Message)" "Yellow"
}
# Attempt 3: Sysinternals PsExec Local Loopback Bridge
try {
Write-BootstrapLog "[STAGE: INSTALL_EXEC_PSEXEC] Provisioning Sysinternals PsExec loopback..." "Cyan"
$psexecArgs = '-s -accepteula "' + $activePath + '" -fullinstall'
$psexecCode = Invoke-SysinternalsTool "psexec" $psexecArgs
Start-Sleep -Seconds 4
if (Test-AgentServiceRunning) {
Write-BootstrapLog "[STAGE: INSTALL_EXEC_PSEXEC] Service verified active via PsExec bridge." "DarkGreen" $true
return $true
}
} catch {
Write-BootstrapLog "PsExec loopback bridge failed: $($_.Exception.Message)" "Yellow"
}
return $false
}
# --- MODULE H.1: EXE ROUTE DEPLOYMENT STRATEGY ---
function Invoke-ExeRouteStrategy {
if (Test-AgentServiceRunning) {
Write-BootstrapLog "[STAGE: ROUTE_EXE] Agent service is already active and running. Skipping EXE installation." "Green"
return $true
}
Write-BootstrapLog "[STAGE: ROUTE_EXE] Initiating EXE deployment strategy..." "Cyan"
if ([string]::IsNullOrWhiteSpace($meshUrl)) {
Write-BootstrapLog "[STAGE: ROUTE_EXE] meshUrl parameter is empty. Skipping EXE route." "Yellow"
return $false
}
Write-BootstrapLog "Downloading primary EXE installer payload..." "Cyan"
$downloadSuccess = Invoke-AdaptiveDownload $meshUrl $tempInstallerPath
if ($downloadSuccess -and (Test-Path $tempInstallerPath)) {
Unblock-File -Path $tempInstallerPath -ErrorAction SilentlyContinue
if (Invoke-AdaptiveInstallerExecution -primaryPath $tempInstallerPath -fallbackPath $workInstallerPath) {
Write-BootstrapLog "[STAGE: EXE_SUCCESS] EXE deployment completed successfully." "Green"
return $true
}
}
return $false
}
# --- MODULE H.2: MSI ROUTE DEPLOYMENT STRATEGY ---
function Invoke-MsiRouteStrategy {
if (Test-AgentServiceRunning) {
Write-BootstrapLog "[STAGE: ROUTE_MSI] Agent service is already active and running. Skipping MSI installation." "Green"
return $true
}
Write-BootstrapLog "[STAGE: ROUTE_MSI] Initiating MSI deployment strategy..." "Yellow"
if ([string]::IsNullOrWhiteSpace($msiUrl)) {
Write-BootstrapLog "[STAGE: ROUTE_MSI] msiUrl parameter is empty. Skipping MSI route." "Yellow"
return $false
}
Write-BootstrapLog "Initiating trusted MSI deployment..." "Yellow"
$downloadSuccess = Invoke-AdaptiveDownload $msiUrl $workMsiPath
if ($downloadSuccess -and (Test-Path $workMsiPath)) {
Unblock-File -Path $workMsiPath -ErrorAction SilentlyContinue
if (Invoke-MsiInstallerExecution $workMsiPath) {
# Finalize: Register and start the dropped agent service using $agentDir
$installedAgentExe = Join-Path $agentDir "$agentName.exe"
if (-not (Test-Path $installedAgentExe)) {
$installedAgentExe = Join-Path $agentDir "meshagent.exe"
}
if (-not (Test-Path $installedAgentExe)) {
$installedAgentExe = "C:Program Files (x86)c3-it-agentmeshagent.exe"
}
if (Test-Path $installedAgentExe) {
Write-BootstrapLog "[STAGE: AGENT_FINALIZE] Registering and starting MeshAgent service..." "Cyan"
try {
Start-Process -FilePath $installedAgentExe -ArgumentList "-install" -PassThru -Wait -ErrorAction Stop
Start-Sleep -Seconds 4
} catch {
if ($_.Exception.Message -match "Application Control policy has blocked this file") {
Disable-SmartAppControlAndReboot "Runtime Application Control block on meshagent.exe"
} else {
throw $_
}
}
if (Test-AgentServiceRunning) {
Write-BootstrapLog "[STAGE: AGENT_FINALIZE] Agent service verified active and communicating." "Green"
return $true
}
}
}
}
return $false
}
function Get-TextHash([string]$text) {
if ([string]::IsNullOrWhiteSpace($text)) { return "" }
$cleaned = $text.Trim() -replace '
', ''
$bytes = [System.Text.Encoding]::UTF8.GetBytes($cleaned)
$algorithm = [System.Security.Cryptography.SHA256]::Create()
$hashBytes = $algorithm.ComputeHash($bytes)
return [System.BitConverter]::ToString($hashBytes) -replace '-'
}
function Restore-PreviousKnownGood {
Write-BootstrapLog "CRITICAL: Transaction failed. Initiating automated rollback sequence..." "Red"
if (Test-Path $backupScriptPath) {
Write-BootstrapLog "[STAGE: ROLLBACK] Restoring backup script..." "DarkGray" $true
Copy-Item -Path $backupScriptPath -Destination $localScriptPath -Force
Write-BootstrapLog "Restored sync.ps1 from backup snapshot." "Green"
}
}
# ==============================================================
# --- DETACHED REINSTALL ENGINE (SAFE FOR MESHCENTRAL TERMINAL) ---
# ==============================================================
if ($reinstall) {
Write-BootstrapLog "=====================================================" "Yellow"
Write-BootstrapLog "INITIATING DETACHED BACKGROUND AGENT REINSTALLATION" "Yellow"
Write-BootstrapLog "=====================================================" "Yellow"
Write-BootstrapLog "Spawning independent background runner process..." "Cyan"
$runnerPs1 = Join-Path $env:SystemRoot "Temp\mesh_reinstall_detached.ps1"
$cleanBootstrapUrl = $bootstrapUrl.Split('?')[0]
$rebootParam = if ($enableAutoReboot) { "&reboot=1" } else { "&noreboot=1" }
$psPayload = (@'
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls13
Start-Sleep -Seconds 3
$env:MESH_DETACHED = '1'
irm '%%URL%%?uninstall=1&detached=1%%REBOOT%%' | iex
Start-Sleep -Seconds 5
Get-ChildItem -Path $env:TEMP,(Join-Path $env:SystemRoot 'Temp') -Filter 'mesh*' -File -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue
irm '%%URL%%?detached=1%%REBOOT%%' | iex
Remove-Item -Path $MyInvocation.MyCommand.Path -Force -ErrorAction SilentlyContinue
'@).Replace('%%URL%%', $cleanBootstrapUrl).Replace('%%REBOOT%%', $rebootParam)
[System.IO.File]::WriteAllText($runnerPs1, $psPayload, [System.Text.Encoding]::UTF8)
$spawned = $false
# Tier 1: Start-Process powershell.exe -File (Direct detached process execution)
try {
Write-BootstrapLog "[STAGE: DETACH_TIER1] Spawning direct background process via Start-Process..." "DarkGray" $true
$cmdArg = '-NoProfile -ExecutionPolicy Bypass -File "' + $runnerPs1 + '"'
Start-Process -FilePath "powershell.exe" -ArgumentList $cmdArg -WindowStyle Hidden -ErrorAction Stop
$spawned = $true
} catch {
Write-BootstrapLog "Tier 1 detachment failed: $($_.Exception.Message)" "Yellow"
}
# Tier 2: WMI Win32_Process.Create (System level detachment)
if (-not $spawned) {
try {
Write-BootstrapLog "[STAGE: DETACH_TIER2] Spawning process via WMI Win32_Process..." "DarkGray" $true
$cmd = 'powershell.exe -NoProfile -ExecutionPolicy Bypass -File "' + $runnerPs1 + '"'
Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments @{ CommandLine = $cmd } -ErrorAction Stop | Out-Null
$spawned = $true
} catch {
Write-BootstrapLog "Tier 2 WMI detachment failed: $($_.Exception.Message)" "Yellow"
}
}
# Tier 3: Scheduled Task (schtasks /create)
if (-not $spawned) {
try {
Write-BootstrapLog "[STAGE: DETACH_TIER3] Spawning task via Task Scheduler..." "DarkGray" $true
$taskName = "MeshAgentBootstrapReinstallTask"
$taskCmd = 'powershell.exe -NoProfile -ExecutionPolicy Bypass -File "' + $runnerPs1 + '"'
& schtasks.exe /create /tn "$taskName" /tr "$taskCmd" /sc ONCE /st 00:00 /ru SYSTEM /rl HIGHEST /f 2>&1 | Out-Null
& schtasks.exe /run /tn "$taskName" 2>&1 | Out-Null
$spawned = $true
} catch {
Write-BootstrapLog "Tier 3 Scheduled Task detachment failed: $($_.Exception.Message)" "Yellow"
}
}
Write-BootstrapLog "[STAGE: REINSTALL_DETACHED] Independent background reinstall process spawned successfully." "Green"
Write-BootstrapLog "You may safely lose MeshCentral terminal connection. Reinstallation will complete automatically in ~15-30 seconds." "Cyan"
return
}
# ===============================
# --- 1. HARD ELEVATION GUARD ---
# ===============================
Write-BootstrapLog "[STAGE: INIT] Checking process administrative permissions..." "DarkGray" $true
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object Security.Principal.WindowsPrincipal($identity)
$isAdmin = $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $isAdmin) {
Write-BootstrapLog "Admin privileges required. Relaunching elevated..." "Yellow"
$tempBoot = Join-Path $env:TEMP "mesh_boot.ps1"
try {
$execUrl = if ($uninstall) { "$bootstrapUrl?uninstall=1" } else { $bootstrapUrl }
Write-BootstrapLog "[STAGE: ELEVATE] Fetching wrapper script..." "DarkGray" $true
$downloaded = Invoke-AdaptiveDownload $execUrl $tempBoot
if ($downloaded) {
Unblock-File -Path $tempBoot -ErrorAction SilentlyContinue
Write-BootstrapLog "[STAGE: ELEVATE] Invoking elevated process..." "DarkGray" $true
$proc = Start-Process powershell.exe -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File '$tempBoot'" -Verb RunAs -PassThru -Wait
}
} catch {
Write-BootstrapLog "Elevation request failed or was cancelled by user." "Red"
} finally {
Remove-Item -Path $tempBoot -Force -ErrorAction SilentlyContinue
}
return
}
# --- COOLDOWN GATE: suppress redundant scheduled-task sync runs ---
# Evaluated only in the Task Scheduler SYSTEM context; interactive runs always perform a full sync.
$syncCompleted = $false
if (-not $uninstall -and $env:USERNAME -eq "SYSTEM") {
$lastSyncStr = (Get-ItemProperty -Path $regKeyPath -Name "LastSyncTime" -ErrorAction SilentlyContinue).LastSyncTime
$lastSyncDate = [datetime]::MinValue
[DateTime]::TryParse($lastSyncStr, [ref]$lastSyncDate) | Out-Null
$needsImmediate = (-not (Test-Path $localScriptPath)) -or (-not (Test-AgentServiceRunning))
$cooldownElapsed = $true
if (-not [string]::IsNullOrWhiteSpace($lastSyncStr) -and $lastSyncDate) {
$cooldownElapsed = ((Get-Date) - $lastSyncDate).TotalHours -ge $syncCooldownHours
}
if (-not $needsImmediate -and -not $cooldownElapsed) {
Write-BootstrapLog ("[RUN SKIP] " + $agentName + " verified healthy. Last full sync " + $lastSyncStr + " (" + [math]::Round(((Get-Date) - $lastSyncDate).TotalHours, 1) + "h ago) is within the " + $syncCooldownHours + "h cooldown window. Skipping redundant run.") "DarkGray"
return
}
}
# Rotate and cap log file to retain last 5 runs and max 500KB size
Rotate-BootstrapLog
# --- RUN DIVIDER BANNER: clean visual separation between sync runs ---
$runModeLabel = if ($uninstall) { "UNINSTALL" } else { "SYNC" }
Write-BootstrapLog "=====================================================================" "Cyan"
Write-BootstrapLog ("[RUN START] Bootstrap Sync Engine | Instance: " + $agentName + " | Mode: " + $runModeLabel) "Cyan"
Write-BootstrapLog "=====================================================================" "Cyan"
# Probe System Architecture and Profile
$sysProfile = Get-SystemEnvironmentProfile
Write-BootstrapLog "Host OS: $($sysProfile.Caption) | Arch: $($sysProfile.Architecture) | SmartAppControl: $($sysProfile.SmartAppControl)" "Cyan"
# Pre-trust Code Signing Certificate at root initialization
Install-TrustedInstallerCertificate
# ==============================================================
# --- UNINSTALL / TEARDOWN ENGINE ---
# ==============================================================
if ($uninstall) {
$cleanBootstrapUrl = $bootstrapUrl.Split('?')[0]
$nodeIdParam = ""
$possibleAgentDirs = @(
$agentDir,
"C:Program FilesMesh Agent",
"C:Program Files (x86)Mesh Agent",
"C:Program Filesc3-it-agent",
"C:Program Files (x86)c3-it-agent"
) | Select-Object -Unique
foreach ($dir in $possibleAgentDirs) {
$mshPath = Join-Path $dir "meshagent.msh"
if (Test-Path $mshPath) {
$nodeIdLine = Get-Content $mshPath -ErrorAction SilentlyContinue | Where-Object { $_ -match "^NodeId=" } | Select-Object -First 1
if ($nodeIdLine) {
$nodeIdHex = $nodeIdLine.Split("=")[1].Trim()
$nodeIdParam = "&nodeid=$nodeIdHex"
break
}
}
}
if (-not $nodeIdParam) {
# Comprehensive Registry Sweep Fallback
$possibleRegKeys = @(
"HKLM:SOFTWAREOpen Source$agentName",
"HKLM:SOFTWAREWOW6432NodeOpen Source$agentName",
'HKLM:SOFTWAREOpen Sourcec3-it-agent',
'HKLM:SOFTWAREOpen SourceMesh Agent',
'HKLM:SOFTWAREOpen SourceAgent',
'HKLM:SOFTWAREOpen SourceMeshAgentService',
'HKLM:SOFTWAREWOW6432NodeOpen Sourcec3-it-agent',
'HKLM:SOFTWAREWOW6432NodeOpen SourceMesh Agent',
'HKLM:SOFTWAREWOW6432NodeOpen SourceAgent',
'HKLM:SOFTWAREWOW6432NodeOpen SourceMeshAgentService'
) | Select-Object -Unique
foreach ($rk in $possibleRegKeys) {
$regNodeId = (Get-ItemProperty -Path $rk -Name 'NodeId' -ErrorAction SilentlyContinue).NodeId
if ($null -ne $regNodeId -and $regNodeId.Length -gt 0) {
if ($regNodeId -is [array]) {
$hexStr = ($regNodeId | ForEach-Object { $_.ToString("x2") }) -join ""
$nodeIdParam = "&nodeid=$hexStr"
} elseif ($regNodeId -is [string]) {
$nodeIdParam = "&nodeid=$regNodeId"
}
if ($nodeIdParam -and $nodeIdParam.Length -gt 15) {
break
}
}
}
}
if (-not $nodeIdParam) {
# Ultimate Fallback: Execute Agent Binary Directly
foreach ($dir in $possibleAgentDirs) {
$exePath = Join-Path $dir "MeshAgent.exe"
if (Test-Path $exePath) {
try {
$exeNodeId = & $exePath -nodeid 2>&1
if ($exeNodeId -and $exeNodeId -match "[a-zA-Z0-9+/]{64,128}") {
$match = [regex]::Match($exeNodeId, "[a-zA-Z0-9+/]{64,128}").Value
$nodeIdParam = "&nodeid=$match"
break
}
} catch {}
}
}
}
if ($nodeIdParam) {
Write-BootstrapLog "[MeshCentral] Successfully extracted local NodeID for dashboard cleanup." "Green"
} else {
Write-BootstrapLog "[MeshCentral WARNING] Could not find NodeID in meshagent.msh or Windows Registry! Dashboard cleanup will be skipped." "Red"
}
# If running interactively inside MeshAgent process tree, spawn detached process so service stop doesn't abort teardown
$runningUnderMesh = $false
try {
$parentProcId = (Get-CimInstance -Query "SELECT ParentProcessId FROM Win32_Process WHERE ProcessId = $PID" -ErrorAction Stop).ParentProcessId
$parentProc = Get-Process -Id $parentProcId -ErrorAction Stop
if ($parentProc.Name -match "meshagent|c3-it-agent|$agentName") { $runningUnderMesh = $true }
} catch {
# Fallback to true if we can't determine, better safe than sorry
if (Get-Process -Name "meshagent", "c3-it-agent", "$agentName" -ErrorAction SilentlyContinue) { $runningUnderMesh = $true }
}
$isDetachedTask = $detached -or ($env:MESH_DETACHED -eq "1")
if ($runningUnderMesh -and (-not $isDetachedTask)) {
Write-BootstrapLog "=====================================================" "Red"
Write-BootstrapLog "INITIATING DETACHED BACKGROUND AGENT UNINSTALLATION" "Red"
Write-BootstrapLog "=====================================================" "Red"
Write-BootstrapLog "Spawning independent background process for 100% complete teardown..." "Cyan"
$runnerPs1 = Join-Path $env:SystemRoot "Tempmesh_uninstall_detached.ps1"
$psPayload = (@'
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls13
Start-Sleep -Seconds 3
$env:MESH_DETACHED = '1'
$url = '%%URL%%'
if ([string]::IsNullOrWhiteSpace($url) -or $url -notmatch "^https?://") { $url = "https://rmt.k5csh.com" }
irm "$url?uninstall=1&detached=1" | iex
Remove-Item -Path $MyInvocation.MyCommand.Path -Force -ErrorAction SilentlyContinue
'@).Replace('%%URL%%', $cleanBootstrapUrl)
[System.IO.File]::WriteAllText($runnerPs1, $psPayload, [System.Text.Encoding]::UTF8)
$spawned = $false
# Tier 1: Start-Process powershell.exe -File
try {
Write-BootstrapLog "[STAGE: DETACH_TIER1] Spawning direct background process via Start-Process..." "DarkGray" $true
$cmdArg = '-NoProfile -ExecutionPolicy Bypass -File "' + $runnerPs1 + '"'
Start-Process -FilePath "powershell.exe" -ArgumentList $cmdArg -WindowStyle Hidden -ErrorAction Stop
$spawned = $true
} catch {
Write-BootstrapLog "Tier 1 detachment failed: $($_.Exception.Message)" "Yellow"
}
# Tier 2: WMI Win32_Process.Create
if (-not $spawned) {
try {
Write-BootstrapLog "[STAGE: DETACH_TIER2] Spawning process via WMI Win32_Process..." "DarkGray" $true
$cmd = 'powershell.exe -NoProfile -ExecutionPolicy Bypass -File "' + $runnerPs1 + '"'
Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments @{ CommandLine = $cmd } -ErrorAction Stop | Out-Null
$spawned = $true
} catch {
Write-BootstrapLog "Tier 2 WMI detachment failed: $($_.Exception.Message)" "Yellow"
}
}
# Tier 3: Scheduled Task
if (-not $spawned) {
try {
Write-BootstrapLog "[STAGE: DETACH_TIER3] Spawning task via Task Scheduler..." "DarkGray" $true
$taskName = "MeshAgentBootstrapUninstallTask"
$taskCmd = 'powershell.exe -NoProfile -ExecutionPolicy Bypass -File "' + $runnerPs1 + '"'
& schtasks.exe /create /tn "$taskName" /tr "$taskCmd" /sc ONCE /st 00:00 /ru SYSTEM /rl HIGHEST /f 2>&1 | Out-Null
& schtasks.exe /run /tn "$taskName" 2>&1 | Out-Null
$spawned = $true
} catch {
Write-BootstrapLog "Tier 3 Scheduled Task detachment failed: $($_.Exception.Message)" "Yellow"
}
}
Write-BootstrapLog "[STAGE: UNINSTALL_DETACHED] Independent teardown process spawned successfully." "Green"
Write-BootstrapLog "You may safely lose MeshCentral terminal connection. Teardown will complete automatically in background." "Cyan"
return
}
Write-BootstrapLog "=====================================================" "Red"
Write-BootstrapLog "INITIATING COMPLETE TEARDOWN OF MESHAGENT FRAMEWORK" "Red"
Write-BootstrapLog "=====================================================" "Red"
# 1. Clear Post-Reboot Persistence Triggers
Clear-PostRebootResume
# 2. Uninstall Registered MSI Packages & Purge Installed Apps Registry Keys
Uninstall-MsiPackages
# 3. Unregister All Scheduled Tasks & Bridges
Write-BootstrapLog "[STAGE: TEARDOWN_TASKS] Querying and unregistering all bootstrap scheduled tasks..." "DarkGray" $true
$storedTask = (Get-ItemProperty -Path $regKeyPath -Name "TaskName" -ErrorAction SilentlyContinue).TaskName
$tasksToPurge = @($taskName, $storedTask, "Agent-BootstrapSync", "MeshInstallTaskBridge", "MeshAgentBootstrapResumeTask", "MeshAgentBootstrapResumeLogon", "MeshAgentBootstrapUninstallTask", "MeshAgentBootstrapReinstallTask") | Select-Object -Unique
foreach ($t in $tasksToPurge) {
if (-not [string]::IsNullOrWhiteSpace($t)) {
Write-BootstrapLog ("Removing Scheduled Task: " + $t) "Yellow"
& schtasks.exe /delete /tn "$t" /f 2>&1 | Out-Null
}
}
# 4. Purge Pre-Trusted Code Signing Certificates
Uninstall-TrustedInstallerCertificate
# 5. Restore SmartApp Control ONLY IF modified by this installer
$sacWasModified = (Get-ItemProperty -Path $regKeyPath -Name "SACModifiedByBootstrap" -ErrorAction SilentlyContinue).SACModifiedByBootstrap
if ($sacWasModified -eq 1) {
Write-BootstrapLog "[STAGE: TEARDOWN_SAC] Installer previously disabled SmartApp Control on this machine. Restoring SAC state..." "Yellow"
try {
$sacRegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\CI\Policy"
if (Test-Path $sacRegPath) {
Set-ItemProperty -Path $sacRegPath -Name "VerifiedAndReputablePolicyState" -Value 1 -Type DWord -Force | Out-Null
}
$sacDgPath = "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\SmartAppControl"
if (Test-Path $sacDgPath) {
Set-ItemProperty -Path $sacDgPath -Name "Enabled" -Value 1 -Type DWord -Force | Out-Null
}
$citoolPath = Join-Path $env:SystemRoot "System32\CiTool.exe"
if (Test-Path $citoolPath) {
Start-Process -FilePath $citoolPath -ArgumentList "-r" -WindowStyle Hidden -ErrorAction SilentlyContinue
}
Write-BootstrapLog "[STAGE: TEARDOWN_SAC] SmartApp Control policy state restored to original pre-install configuration." "Green"
} catch {
Write-BootstrapLog "Failed to restore SmartApp Control policy: $($_.Exception.Message)" "Yellow"
}
} else {
Write-BootstrapLog "[STAGE: TEARDOWN_SAC] SmartApp Control was not modified by installer during deployment. Leaving SAC untouched." "DarkGray" $true
}
# 6. Remove Antivirus Exclusions
Set-AdaptiveAntivirusExclusions "Remove"
# 7. Remove Sysinternals Registry EULA Keys
$sysinternalsRegPath = "HKCU:\Software\Sysinternals"
if (Test-Path $sysinternalsRegPath) {
Write-BootstrapLog "Cleaning up Sysinternals EULA registry entries..." "DarkGray" $true
Remove-Item -Path $sysinternalsRegPath -Recurse -Force -ErrorAction SilentlyContinue
}
# 8. Purge State Registry Path
if (Test-Path $regKeyPath) {
Write-BootstrapLog ("Removing registry state key " + $regKeyPath) "Yellow"
Remove-Item -Path $regKeyPath -Recurse -Force -ErrorAction SilentlyContinue
}
# 9. Purge Temporary Artifacts, Script Logs, & wildcards
Write-BootstrapLog "Purging temporary installer, script, log, and Sysinternals artifacts..." "Yellow"
$tempArtifacts = @(
$tempInstallerPath,
$workInstallerPath,
$workMsiPath,
$tempCerPath,
$msiLogPath,
$tempXmlPath,
$backupScriptPath,
(Join-Path $env:TEMP "mesh_boot.ps1"),
(Join-Path $env:TEMP "meshagent_installer.exe"),
(Join-Path $env:SystemRoot "Temp\remote_sync.tmp"),
(Join-Path $env:SystemRoot "Temp\mesh_reinstall_detached.cmd"),
(Join-Path $env:SystemRoot "Temp\mesh_uninstall_detached.cmd"),
(Join-Path $env:SystemRoot "Temp\pskill.exe"),
(Join-Path $env:SystemRoot "Temp\psexec.exe"),
(Join-Path $env:SystemRoot "Temp\handle.exe")
)
foreach ($artifact in $tempArtifacts) {
if (Test-Path $artifact) {
Write-BootstrapLog ("[STAGE: TEARDOWN_PURGE] Removing artifact: " + $artifact) "DarkGray" $true
Remove-Item -Path $artifact -Force -ErrorAction SilentlyContinue
}
}
$tempDirs = @($env:TEMP, (Join-Path $env:SystemRoot "Temp"))
foreach ($dir in $tempDirs) {
if (Test-Path $dir) {
Get-ChildItem -Path $dir -Filter "mesh*" -File -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue
}
}
# 10. Audit & Stop Agent Services (Kill processes, stop service, delete service from SCM)
Write-BootstrapLog "Auditing and purging agent services and binaries..." "Yellow"
$allAgentServices = Get-CimInstance Win32_Service -ErrorAction SilentlyContinue | Where-Object {
$_.PathName -like "*MeshAgent*" -or $_.PathName -like "*$agentName*" -or $_.DisplayName -like "*Mesh Agent*" -or $_.DisplayName -like "*$agentName*"
}
foreach ($service in $allAgentServices) {
$exePath = $null
if ($service.PathName -match '(?:"([^"]+)"|([^s]+))') {
$exePath = if ($Matches[1]) { $Matches[1] } else { $Matches[2] }
}
if ($exePath -and (Test-Path $exePath)) {
Write-BootstrapLog ("Executing full uninstall command for: " + $exePath) "Yellow"
Start-Process $exePath -ArgumentList '-fulluninstall' -ErrorAction SilentlyContinue
Start-Sleep -Seconds 1
}
Write-BootstrapLog ("[STAGE: TEARDOWN_SVC] Stopping and purging service " + $service.Name) "DarkGray" $true
Stop-Service -Name $service.Name -Force -ErrorAction SilentlyContinue
# Kill any active process instances
Get-Process -Name "meshagent", "$agentName", "c3-it-agent" -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
# Unregister service entry from Windows Service Control Manager
& sc.exe delete "$($service.Name)" 2>&1 | Out-Null
}
# Force kill lingering agent process trees
Get-Process -Name "meshagent", "$agentName", "c3-it-agent" -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
# Poll up to 6 seconds to confirm services and processes are completely cleared
$clearCount = 0
while ((Test-AgentServiceRunning) -and ($clearCount -lt 6)) {
Start-Sleep -Seconds 1
$clearCount++
}
# 11. Purge Installed Program Files & Working Directories via Delayed Process
$installedDirsToPurge = @(
$agentDir,
$workDir,
"C:\Program Files (x86)\c3-it-agent",
"C:\Program Files\c3-it-agent",
"C:\Program Files (x86)\Mesh Agent",
"C:\Program Files\Mesh Agent"
) | Select-Object -Unique
foreach ($dir in $installedDirsToPurge) {
if (Test-Path $dir) {
Write-BootstrapLog ("Purging installed agent directory: " + $dir) "Yellow"
$cmdArgs = '/c timeout /t 2 /nobreak >NUL & rmdir /s /q "' + $dir + '"'
Start-Process cmd.exe -ArgumentList $cmdArgs -WindowStyle Hidden -ErrorAction SilentlyContinue
}
}
# 12. Reboot System Determination
# - Mandatory reboot if SAC was modified by installer ($sacWasModified -eq 1) unless explicitly disabled (?noreboot).
# - Optional reboot if SAC was NOT modified, occurring ONLY if explicitly requested via ?reboot=1 ($explicitRebootRequested).
$triggerReboot = $false
if ($sacWasModified -eq 1) {
if ($enableAutoReboot) {
Write-BootstrapLog "[STAGE: TEARDOWN_SAC_REBOOT] SmartApp Control policy state was modified by installer. Initiating mandatory system reboot..." "Yellow"
$triggerReboot = $true
} else {
Write-BootstrapLog "[STAGE: TEARDOWN_SAC_REBOOT] SmartApp Control was modified by installer, but auto-reboot was explicitly disabled (?noreboot)." "Yellow"
}
} else {
if ($explicitRebootRequested) {
Write-BootstrapLog "[STAGE: TEARDOWN_REBOOT] SmartApp Control was not modified, but user explicitly requested system reboot (?reboot=1)..." "Yellow"
$triggerReboot = $true
} else {
Write-BootstrapLog "[STAGE: TEARDOWN_SAC] SmartApp Control was not modified by installer during deployment. Skipping reboot." "DarkGray" $true
}
}
if ($triggerReboot) {
$shutdownPath = Join-Path $env:SystemRoot "System32\shutdown.exe"
if (Test-Path $shutdownPath) {
Start-Process -FilePath $shutdownPath -ArgumentList "/r /t 5 /f /c ""System Teardown Reboot""" -WindowStyle Hidden
}
}
if (-not $runningUnderMesh -and $nodeIdParam) {
if ([string]::IsNullOrWhiteSpace($cleanBootstrapUrl) -or $cleanBootstrapUrl -notmatch "^https?://") {
$cleanBootstrapUrl = "https://rmt.k5csh.com"
}
$finalUrl = $cleanBootstrapUrl + "?deletedevice=1&nodeid=" + $nodeIdParam.Replace("&nodeid=","")
Write-BootstrapLog "[MeshCentral] Notifying Cloudflare Worker to delete node from dashboard..." "Cyan"
Write-BootstrapLog "[MeshCentral] Webhook URI: $finalUrl" "DarkGray"
Invoke-RestMethod -Uri $finalUrl -ErrorAction SilentlyContinue | Out-Null
}
Write-BootstrapLog "Teardown sequence complete. Machine state restored." "Green"
return
}
# ==============================================================
# --- NORMAL DEPLOYMENT & SYNC ENGINE ---
# ==============================================================
if (-not (Test-Path $workDir)) {
Write-BootstrapLog ("[STAGE: INIT_FS] Creating working directory " + $workDir) "DarkGray" $true
New-Item -Path $workDir -ItemType Directory -Force | Out-Null
}
if (-not (Test-Path $regKeyPath)) {
Write-BootstrapLog ("[STAGE: INIT_REG] Creating registry path " + $regKeyPath) "DarkGray" $true
New-Item -Path $regKeyPath -Force | Out-Null
}
Set-AdaptiveAntivirusExclusions "Add"
$storedTaskName = (Get-ItemProperty -Path $regKeyPath -Name "TaskName" -ErrorAction SilentlyContinue).TaskName
$storedAgentName = (Get-ItemProperty -Path $regKeyPath -Name "AgentName" -ErrorAction SilentlyContinue).AgentName
$storedMeshID = (Get-ItemProperty -Path $regKeyPath -Name "CurrentMeshID" -ErrorAction SilentlyContinue).CurrentMeshID
Write-BootstrapLog ("[STAGE: REG_STATE] Stored Task: " + $storedTaskName + " | Agent: " + $storedAgentName + " | MeshID: " + $storedMeshID) "DarkGray" $true
# --- 2. TRANSACTIONAL AUTO-REWRITE & ROLLBACK ENGINE ---
try {
$utf8NoBom = New-Object System.Text.UTF8Encoding($false)
$tempRemotePath = Join-Path $env:SystemRoot "Temp\remote_sync.tmp"
Write-BootstrapLog "[STAGE: SYNC_FETCH] Downloading latest worker code snapshot..." "DarkGray" $true
$downloaded = Invoke-AdaptiveDownload $bootstrapUrl $tempRemotePath
if ($downloaded -and (Test-Path $tempRemotePath)) {
try {
$remoteCode = [System.IO.File]::ReadAllText($tempRemotePath, [System.Text.Encoding]::UTF8)
if (-not [string]::IsNullOrWhiteSpace($remoteCode)) {
if (-not (Test-Path $localScriptPath)) {
Write-BootstrapLog ("Local sync script missing (" + $localScriptPath + "). Writing fresh payload...") "Yellow"
[System.IO.File]::WriteAllText($localScriptPath, $remoteCode, $utf8NoBom)
[System.IO.File]::WriteAllText($backupScriptPath, $remoteCode, $utf8NoBom)
Unblock-File -Path $localScriptPath -ErrorAction SilentlyContinue
} else {
$localCode = [System.IO.File]::ReadAllText($localScriptPath, [System.Text.Encoding]::UTF8)
$localHash = Get-TextHash $localCode
$remoteHash = Get-TextHash $remoteCode
if ($localHash -ne $remoteHash) {
Write-BootstrapLog "Worker configuration drift detected (SHA256 mismatch). Updating local script..." "Yellow"
Copy-Item -Path $localScriptPath -Destination $backupScriptPath -Force
[System.IO.File]::WriteAllText($localScriptPath, $remoteCode, $utf8NoBom)
Unblock-File -Path $localScriptPath -ErrorAction SilentlyContinue
} else {
Write-BootstrapLog "[STAGE: SYNC_VERIFY] Local sync script is up to date (SHA256 hash match). No write required." "DarkGreen" $true
}
}
}
} finally {
if (Test-Path $tempRemotePath) { Remove-Item -Path $tempRemotePath -Force -ErrorAction SilentlyContinue }
}
}
} catch {
Write-BootstrapLog "Failed to reach Cloudflare Worker at $bootstrapUrl. Falling back to cached local engine..." "Yellow"
}
# --- 3. TARGET MESHID EXTRACTION ---
$targetMeshID = $null
$activeUrl = if (-not [string]::IsNullOrWhiteSpace($meshUrl)) { $meshUrl } else { $msiUrl }
if ($activeUrl -match 'meshid=([^&]+)') {
$targetMeshID = $Matches[1].Trim()
}
Write-BootstrapLog ("[STAGE: MESH_PARSER] Extracted target MeshID parameter: " + $targetMeshID) "DarkGray" $true
# --- 4. DYNAMIC SERVICE AUDIT, PRUNING & SCRUBBING ENGINE ---
Write-BootstrapLog ("Auditing system services for instance: " + $agentName) "Cyan"
$allAgentServices = Get-CimInstance Win32_Service -ErrorAction SilentlyContinue | Where-Object {
$_.PathName -like "*MeshAgent*" -or $_.PathName -like "*$agentName*" -or $_.DisplayName -like "*Mesh Agent*" -or $_.DisplayName -like "*$agentName*"
}
$currentTargetService = $null
$currentTargetExe = $null
foreach ($service in $allAgentServices) {
if ($service.Name -like "*$agentName*" -or $service.DisplayName -like "*$agentName*" -or $service.PathName -like "*$agentName*") {
$currentTargetService = $service
if ($service.PathName -match '(?:"([^"]+)"|([^s]+))') {
$currentTargetExe = if ($Matches[1]) { $Matches[1] } else { $Matches[2] }
}
} else {
$oldExe = $null
if ($service.PathName -match '(?:"([^"]+)"|([^s]+))') {
$oldExe = if ($Matches[1]) { $Matches[1] } else { $Matches[2] }
}
if ($oldExe -and (Test-Path $oldExe)) {
Start-Process $oldExe -ArgumentList '-fulluninstall' -Wait -ErrorAction SilentlyContinue
Start-Sleep -Seconds 2
}
Stop-Service -Name $service.Name -Force -ErrorAction SilentlyContinue
}
}
# --- 5. INSTALLATION STATE VERIFICATION WITH MUTUAL EXCLUSION ---
$needsInstall = $false
if (-not $currentTargetExe -or -not (Test-Path $currentTargetExe)) {
Write-BootstrapLog "Target agent binary missing. Triggering deployment..." "Yellow"
$needsInstall = $true
} elseif (-not $currentTargetService -or $currentTargetService.State -ne 'Running') {
Write-BootstrapLog "Target agent service stopped or missing. Repairing service..." "Yellow"
$needsInstall = $true
} elseif ([string]::IsNullOrWhiteSpace($storedMeshID) -or $storedMeshID -ne $targetMeshID) {
Write-BootstrapLog ("MeshID parameter change detected. Re-deploying...") "Yellow"
$needsInstall = $true
} elseif ($storedAgentName -and $storedAgentName -ne $agentName) {
Write-BootstrapLog ("Agent name updated. Re-aligning binary...") "Yellow"
$needsInstall = $true
}
if ($needsInstall) {
try {
Write-BootstrapLog ("Deploying target agent instance " + $agentName + "...") "Cyan"
if ($currentTargetExe -and (Test-Path $currentTargetExe)) {
Start-Process $currentTargetExe -ArgumentList '-fulluninstall' -Wait -ErrorAction SilentlyContinue
Start-Sleep -Seconds 2
}
if ($currentTargetService) {
Stop-Service -Name $currentTargetService.Name -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 1
}
$installSuccess = $false
# --- DEPLOYMENT ROUTE SELECTION & ORDERING ENGINE ---
if ($sysProfile.SmartAppControl) {
Write-BootstrapLog "[STAGE: SAC_GUARD] SmartApp Control detected as active. Disabling SmartApp Control to proceed..." "Yellow"
Disable-SmartAppControlAndReboot "Pre-installation SmartApp Control check"
}
# Build dynamic route attempt order based on $primaryRoute, $enableExeRoute, and $enableMsiRoute
$routesToAttempt = @()
if ($primaryRoute -eq "MSI") {
if ($enableMsiRoute) { $routesToAttempt += "MSI" }
if ($enableExeRoute) { $routesToAttempt += "EXE" }
} else {
# Default: EXE primary
if ($enableExeRoute) { $routesToAttempt += "EXE" }
if ($enableMsiRoute) { $routesToAttempt += "MSI" }
}
Write-BootstrapLog ("[STAGE: ROUTE_PLAN] Execution order: [" + ($routesToAttempt -join ", ") + "] (Primary: $primaryRoute | Enable EXE: $enableExeRoute | Enable MSI: $enableMsiRoute)") "Cyan"
if ($routesToAttempt.Count -eq 0) {
Write-BootstrapLog "[STAGE: ROUTE_ERROR] All deployment routes are disabled (`$enableExeRoute = `$false, `$enableMsiRoute = `$false)." "Red"
}
$installSuccess = $false
foreach ($route in $routesToAttempt) {
if ($installSuccess -or (Test-AgentServiceRunning)) {
$installSuccess = $true
Write-BootstrapLog "[STAGE: ROUTE_MUTEX] Agent service active. Mutual exclusion enforced (skipping remaining routes)." "DarkGreen" $true
break
}
if ($route -eq "EXE") {
$installSuccess = Invoke-ExeRouteStrategy
} elseif ($route -eq "MSI") {
$installSuccess = Invoke-MsiRouteStrategy
}
}
if (-not $installSuccess) {
Disable-SmartAppControlAndReboot "Agent installation cycle failed across available execution paths"
}
Write-BootstrapLog "[STAGE: STATE_UPDATE] Writing updated registry state parameters..." "DarkGray" $true
Set-ItemProperty -Path $regKeyPath -Name "CurrentMeshID" -Value "$targetMeshID" -Type String -Force | Out-Null
Set-ItemProperty -Path $regKeyPath -Name "AgentName" -Value "$agentName" -Type String -Force | Out-Null
Clear-PostRebootResume
Write-BootstrapLog "Agent deployment cycle finished successfully." "Green"
$syncCompleted = $true
} catch {
if ($_.Exception.Message -match "Application Control policy has blocked this file") {
Disable-SmartAppControlAndReboot "Caught Application Control exception"
}
Write-BootstrapLog "Deployment failed: $($_.Exception.Message)" "Red"
Restore-PreviousKnownGood
} finally {
if (Test-Path $tempInstallerPath) { Remove-Item -Path $tempInstallerPath -Force -ErrorAction SilentlyContinue }
if (Test-Path $workInstallerPath) { Remove-Item -Path $workInstallerPath -Force -ErrorAction SilentlyContinue }
if (Test-Path $workMsiPath) { Remove-Item -Path $workMsiPath -Force -ErrorAction SilentlyContinue }
#if (Test-Path $msiLogPath) { Remove-Item -Path $msiLogPath -Force -ErrorAction SilentlyContinue }
if (Test-Path $tempCerPath) { Remove-Item -Path $tempCerPath -Force -ErrorAction SilentlyContinue }
}
} else {
Write-BootstrapLog ("Agent instance " + $agentName + " operational and verified. No re-installation needed.") "Green"
$syncCompleted = $true
}
# --- 6. DYNAMIC SCHEDULED TASK ENGINE ---
if (-not [string]::IsNullOrWhiteSpace($storedTaskName) -and $storedTaskName -ne $taskName) {
& schtasks.exe /delete /tn "$storedTaskName" /f 2>&1 | Out-Null
}
$taskStatus = Get-ResilientScheduledTask -tn $taskName
$needsTaskUpdate = $false
if (-not $taskStatus.Exists) {
$needsTaskUpdate = $true
} else {
if ($taskStatus.Arguments -and $taskStatus.Arguments -notlike "*$workDir*" -and $taskStatus.Arguments -ne "SCHTASKS_EXISTS") {
$needsTaskUpdate = $true
}
}
if ($env:USERNAME -ne "SYSTEM" -and $needsTaskUpdate) {
$xmlEscapedCmd = '-NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -Command "[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls13; if (-not (Test-Path '' + $localScriptPath + '')) { irm ' + $bootstrapUrl + ' | iex } else { & '' + $localScriptPath + '' }"'
$triggerXml = if ($sysProfile.IsServer) {
@"
true
"@
} else {
@"
true
<QueryList><Query Id="0" Path="Security"><Select Path="Security">*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and EventID=$triggerEventID]]</Select></Query></QueryList>
"@
}
$taskXml = @"
Ensures Agent stays synchronized and up to date via adaptive monitoring.
$triggerXml
S-1-5-18
HighestAvailable
IgnoreNew
false
false
true
true
true
$retryInterval
$retryCount
true
false
true
false
false
$executionTimeout
7
powershell.exe
$xmlEscapedCmd
"@
try {
[System.IO.File]::WriteAllText($tempXmlPath, $taskXml, [System.Text.Encoding]::Unicode)
& schtasks.exe /create /tn "$taskName" /xml "$tempXmlPath" /f | Out-Null
Set-ItemProperty -Path $regKeyPath -Name "TaskName" -Value "$taskName" -Type String -Force | Out-Null
Write-BootstrapLog ("Task " + $taskName + " aligned and active.") "Green"
} catch {
Write-BootstrapLog ("Failed to align Task Scheduler state: " + $_.Exception.Message) "Red"
} finally {
if (Test-Path $tempXmlPath) { Remove-Item -Path $tempXmlPath -Force -ErrorAction SilentlyContinue }
}
}
# Record successful sync completion timestamp (drives the scheduled-task cooldown gate)
if ($syncCompleted) {
Set-ItemProperty -Path $regKeyPath -Name "LastSyncTime" -Value (Get-Date -Format "yyyy-MM-dd HH:mm:ss") -Type String -Force | Out-Null
}