From 7d240325e5fac50602f1fe713d703971d22a5774 Mon Sep 17 00:00:00 2001 From: Nicole Rappe Date: Fri, 5 Sep 2025 15:01:54 -0600 Subject: [PATCH] Consolidated UAC Prompts in Agent Deployment --- Borealis.ps1 | 47 ++++++++++++--------- Data/Agent/Scripts/register_agent_tasks.ps1 | 31 ++++++++++++-- Data/Agent/agent_deployment.py | 2 +- 3 files changed, 57 insertions(+), 23 deletions(-) diff --git a/Borealis.ps1 b/Borealis.ps1 index 9e9bb5e..d1b295e 100644 --- a/Borealis.ps1 +++ b/Borealis.ps1 @@ -328,10 +328,14 @@ function Ensure-AgentTasks { param( [string]$ScriptRoot ) - $supName = 'Borealis Agent - Supervisor' - $py = Join-Path $ScriptRoot 'Agent\Scripts\python.exe' - $supScript= Join-Path $ScriptRoot 'Data\Agent\agent_supervisor.py' - $wdName = 'Borealis Agent - Watchdog' + $supName = 'Borealis Agent - Supervisor' + $py = Join-Path $ScriptRoot 'Agent\Scripts\python.exe' + $supScript = Join-Path $ScriptRoot 'Data\Agent\agent_supervisor.py' + $wdName = 'Borealis Agent - Watchdog' + # Per-user tray helper task (ensure within same elevation to avoid second UAC) + $userTaskName = 'Borealis Agent' + $userExe = Join-Path $ScriptRoot 'Agent\Scripts\pythonw.exe' + $userScript = Join-Path $ScriptRoot 'Agent\Borealis\tray_launcher.py' # Elevate and run the external registrar script with parameters $regScript = Join-Path $ScriptRoot 'Data\Agent\Scripts\register_agent_tasks.ps1' @@ -340,19 +344,28 @@ function Ensure-AgentTasks { if (-not (Test-Path $wdSource)) { Write-Host "Watchdog script not found: $wdSource" -ForegroundColor Red; return } # Launch registrar elevated using -EncodedCommand to avoid quoting/binding issues - $qSupName = $supName -replace "'","''" - $qPy = $py -replace "'","''" - $qSupScript= $supScript-replace "'","''" - $qWdName = $wdName -replace "'","''" - $qWdSource = $wdSource -replace "'","''" - $qRegScript= $regScript-replace "'","''" + $qSupName = $supName -replace "'","''" + $qPy = $py -replace "'","''" + $qSupScript = $supScript -replace "'","''" + $qWdName = $wdName -replace "'","''" + $qWdSource = $wdSource -replace "'","''" + $qRegScript = $regScript -replace "'","''" + $qUserTaskName = $userTaskName -replace "'","''" + $qUserExe = $userExe -replace "'","''" + $qUserScript = $userScript -replace "'","''" + $currentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name + $qUserPrincipal= $currentUser -replace "'","''" $inline = @" `$p = @{ - SupName = '$qSupName' - PythonExe = '$qPy' - SupScript = '$qSupScript' - WdName = '$qWdName' - WdSource = '$qWdSource' + SupName = '$qSupName' + PythonExe = '$qPy' + SupScript = '$qSupScript' + WdName = '$qWdName' + WdSource = '$qWdSource' + UserTaskName = '$qUserTaskName' + UserExe = '$qUserExe' + UserScript = '$qUserScript' + UserPrincipal = '$qUserPrincipal' } & '$qRegScript' @p "@ @@ -421,10 +434,6 @@ function InstallOrUpdate-BorealisAgent { Write-Host "`nConfiguring Borealis Agent (tasks)..." -ForegroundColor Blue Write-Host "====================================================================================" Ensure-AgentTasks -ScriptRoot $scriptDir - - # Ensure per-user logon task for helper - $deployScript = Join-Path (Join-Path $scriptDir 'Agent\Borealis') 'agent_deployment.py' - try { & (Join-Path $scriptDir 'Agent\Scripts\python.exe') -W ignore::SyntaxWarning $deployScript task-ensure | Out-Null } catch {} } # ---------------------- Main ---------------------- diff --git a/Data/Agent/Scripts/register_agent_tasks.ps1 b/Data/Agent/Scripts/register_agent_tasks.ps1 index c1184ea..b1a31d9 100644 --- a/Data/Agent/Scripts/register_agent_tasks.ps1 +++ b/Data/Agent/Scripts/register_agent_tasks.ps1 @@ -3,7 +3,12 @@ param( [Parameter(Mandatory=$true)] [string]$PythonExe, [Parameter(Mandatory=$true)] [string]$SupScript, [Parameter(Mandatory=$true)] [string]$WdName, - [Parameter(Mandatory=$true)] [string]$WdSource + [Parameter(Mandatory=$true)] [string]$WdSource, + # Optional per-user logon task (to avoid a second UAC prompt elsewhere) + [string]$UserTaskName = 'Borealis Agent', + [string]$UserExe = $null, + [string]$UserScript = $null, + [string]$UserPrincipal = $null ) $ErrorActionPreference = 'Continue' @@ -17,7 +22,7 @@ try { $supArg = ('-W ignore::SyntaxWarning "{0}"' -f $SupScript) $supAction = New-ScheduledTaskAction -Execute $PythonExe -Argument $supArg $supTrigger = New-ScheduledTaskTrigger -AtStartup - $supSettings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -Hidden -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1) + $supSettings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -Hidden -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1) -ExecutionTimeLimit ([TimeSpan]::Zero) Register-ScheduledTask -TaskName $SupName -Action $supAction -Trigger $supTrigger -Settings $supSettings -Principal $principal -Force | Out-Null # Watchdog script deployment @@ -30,12 +35,32 @@ try { $wdArg = ('-NoProfile -ExecutionPolicy Bypass -File "{0}" -SupervisorTaskName "{1}"' -f $wdDest, $SupName) $wdAction = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument $wdArg $wdTrigger = New-ScheduledTaskTrigger -Once -At ([datetime]::Now.AddMinutes(1)) -RepetitionInterval (New-TimeSpan -Minutes 5) -RepetitionDuration (New-TimeSpan -Days 365) - $wdSettings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -Hidden + $wdSettings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -Hidden -ExecutionTimeLimit ([TimeSpan]::Zero) Register-ScheduledTask -TaskName $WdName -Action $wdAction -Trigger $wdTrigger -Settings $wdSettings -Principal $principal -Force | Out-Null # Ensure supervisor is running Start-ScheduledTask -TaskName $SupName | Out-Null + # Optionally ensure a per-user logon task for the tray helper without a separate elevation + if ($UserExe -and $UserScript) { + try { + $targetUser = $UserPrincipal + if (-not $targetUser -or $targetUser -eq '') { + $targetUser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name + } + try { Unregister-ScheduledTask -TaskName $UserTaskName -Confirm:$false -ErrorAction SilentlyContinue } catch {} + $usrArg = ('-W ignore::SyntaxWarning "{0}"' -f $UserScript) + $usrAction = New-ScheduledTaskAction -Execute $UserExe -Argument $usrArg + $usrTrig = New-ScheduledTaskTrigger -AtLogOn + $usrSet = New-ScheduledTaskSettingsSet -Hidden -ExecutionTimeLimit ([TimeSpan]::Zero) + $usrPrin = New-ScheduledTaskPrincipal -UserId $targetUser -LogonType Interactive -RunLevel Limited + Register-ScheduledTask -TaskName $UserTaskName -Action $usrAction -Trigger $usrTrig -Settings $usrSet -Principal $usrPrin -Force | Out-Null + Start-ScheduledTask -TaskName $UserTaskName | Out-Null + } catch { + Write-Warning "Failed to register per-user logon task '$UserTaskName': $_" + } + } + } catch { Write-Error $_ exit 1 diff --git a/Data/Agent/agent_deployment.py b/Data/Agent/agent_deployment.py index e6ead35..824fc4e 100644 --- a/Data/Agent/agent_deployment.py +++ b/Data/Agent/agent_deployment.py @@ -126,7 +126,7 @@ $arg = "-W ignore::SyntaxWarning {paths['agent_script']}" try {{ Unregister-ScheduledTask -TaskName $task -Confirm:$false -ErrorAction SilentlyContinue }} catch {{}} $action = New-ScheduledTaskAction -Execute $py -Argument $arg $trigger= New-ScheduledTaskTrigger -AtLogOn -$settings = New-ScheduledTaskSettingsSet -Hidden +$settings = New-ScheduledTaskSettingsSet -Hidden -ExecutionTimeLimit ([TimeSpan]::Zero) Register-ScheduledTask -TaskName $task -Action $action -Trigger $trigger -Settings $settings -Force | Out-Null Start-ScheduledTask -TaskName $task | Out-Null """