diff --git a/scripts/install-offsite-backup-task.ps1 b/scripts/install-offsite-backup-task.ps1 index 1bad989..053de5b 100644 --- a/scripts/install-offsite-backup-task.ps1 +++ b/scripts/install-offsite-backup-task.ps1 @@ -10,6 +10,7 @@ $ErrorActionPreference = "Stop" $repoRoot = Split-Path -Parent $PSScriptRoot $envFile = Join-Path $repoRoot ".env" $syncScript = Join-Path $PSScriptRoot "sync-voidbot-backup-offsite.ps1" +$hiddenLauncher = Join-Path $PSScriptRoot "run-hidden-powershell.vbs" function Read-DotEnv { param( @@ -67,7 +68,8 @@ if (-not ($config.ContainsKey("OFFSITE_BACKUP_SSH_TARGET")) -or [string]::IsNull } $runAt = [DateTime]::ParseExact($taskTimeValue, "HH:mm", [System.Globalization.CultureInfo]::InvariantCulture) -$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -File `"$syncScript`"" +# Use WSH as a GUI host so the interactive task can stay hidden without flashing a console. +$action = New-ScheduledTaskAction -Execute "wscript.exe" -Argument "//B //nologo `"$hiddenLauncher`" -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -File `"$syncScript`"" $trigger = New-ScheduledTaskTrigger -Daily -At $runAt $settings = New-ScheduledTaskSettingsSet -StartWhenAvailable -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit (New-TimeSpan -Hours 6) $principal = New-ScheduledTaskPrincipal -UserId "$env:USERDOMAIN\$env:USERNAME" -LogonType Interactive -RunLevel Limited @@ -79,7 +81,7 @@ Write-Host "Installed scheduled task: $taskNameValue" Write-Host "Schedule: daily at $taskTimeValue" Write-Host "Task runs as: $($env:USERDOMAIN)\$($env:USERNAME)" Write-Host "Logon mode: Interactive" -Write-Host "Window mode: Hidden" +Write-Host "Launcher: wscript.exe hidden PowerShell shim" Write-Host "Execution time limit: 6 hours" if ($RunNow) { diff --git a/scripts/install-operations-watchdog-task.ps1 b/scripts/install-operations-watchdog-task.ps1 index 817023b..b0cdc43 100644 --- a/scripts/install-operations-watchdog-task.ps1 +++ b/scripts/install-operations-watchdog-task.ps1 @@ -11,6 +11,7 @@ $ProgressPreference = "SilentlyContinue" $repoRoot = Split-Path -Parent $PSScriptRoot $envFile = Join-Path $repoRoot ".env" $checkScript = Join-Path $PSScriptRoot "check-voidbot-operations.ps1" +$hiddenLauncher = Join-Path $PSScriptRoot "run-hidden-powershell.vbs" function Read-DotEnv { param( @@ -76,7 +77,8 @@ if (-not ($config.ContainsKey("DISCORD_OWNER_ID")) -or [string]::IsNullOrWhiteSp } $startAt = (Get-Date).AddMinutes(5) -$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -File `"$checkScript`" -NotifyOwner -FailOnIssues" +# Use WSH as a GUI host so the interactive task can stay hidden without flashing a console. +$action = New-ScheduledTaskAction -Execute "wscript.exe" -Argument "//B //nologo `"$hiddenLauncher`" -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -File `"$checkScript`" -NotifyOwner -FailOnIssues" $trigger = New-ScheduledTaskTrigger -Once -At $startAt -RepetitionInterval (New-TimeSpan -Minutes $intervalMinutesValue) -RepetitionDuration (New-TimeSpan -Days 3650) $settings = New-ScheduledTaskSettingsSet -StartWhenAvailable -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit (New-TimeSpan -Minutes 15) $principal = New-ScheduledTaskPrincipal -UserId "$env:USERDOMAIN\$env:USERNAME" -LogonType Interactive -RunLevel Limited @@ -88,7 +90,7 @@ Write-Host "Installed scheduled task: $taskNameValue" Write-Host "Schedule: every $intervalMinutesValue minute(s), starting at $($startAt.ToString('yyyy-MM-dd HH:mm'))" Write-Host "Task runs as: $($env:USERDOMAIN)\$($env:USERNAME)" Write-Host "Logon mode: Interactive" -Write-Host "Window mode: Hidden" +Write-Host "Launcher: wscript.exe hidden PowerShell shim" Write-Host "Execution time limit: 15 minutes" if ($RunNow) { diff --git a/scripts/run-hidden-powershell.vbs b/scripts/run-hidden-powershell.vbs new file mode 100644 index 0000000..2a4d85b --- /dev/null +++ b/scripts/run-hidden-powershell.vbs @@ -0,0 +1,20 @@ +Option Explicit + +Dim shell +Dim command +Dim i +Dim exitCode + +Set shell = CreateObject("WScript.Shell") +command = QuoteArg(shell.ExpandEnvironmentStrings("%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe")) + +For i = 0 To WScript.Arguments.Count - 1 + command = command & " " & QuoteArg(CStr(WScript.Arguments(i))) +Next + +exitCode = shell.Run(command, 0, True) +WScript.Quit exitCode + +Function QuoteArg(value) + QuoteArg = """" & Replace(value, """", """""") & """" +End Function