1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
<#
.SYNOPSIS
Install/remove/query/run/end the "MeshBay Node" boot-time Scheduled Task.
.DESCRIPTION
A real Windows Service runs under LocalSystem/NetworkService before anyone
signs in -- but those accounts have no normal user profile, and this app's
entire design keeps node.toml, the keystore and all data under the signed-in
user's own %LOCALAPPDATA%\meshbay\. Running as LocalSystem would not find
any of it.
The middle ground, and what this script sets up: a Scheduled Task that runs
AS THIS USER at system boot, without needing them to sign in first -- an
S4U (Service For User) logon: no password stored anywhere, and unlike
LocalSystem it loads this account's own profile, so %LOCALAPPDATA%\meshbay\
keeps working with zero changes. The cost: S4U carries no network
credential (no reaching a domain share as this user), which the node
never needed -- everything it touches is local disk plus outbound
internet.
Install uses Register-ScheduledTask with -LogonType S4U, not
`schtasks /create`: schtasks only infers the logon type from whether /rp
is present, and both readings were tried and broke on this exact machine's
blank-password account (common on a personal PC) -- `/rp ""` fails
credential validation ("the user name or password is incorrect", even
though nothing is wrong), and omitting /rp registers "Interactive only"
instead of S4U, which never runs at boot and doesn't launch anything even
run on demand while signed in (both confirmed live, 2026-09-05).
-LogonType S4U is explicit, no inference. remove/status/run/end have no
such ambiguity and stay on schtasks.exe.
Mirrors meshbay_node.platform.service_install/_remove/_status/_run/_end --
same TASK_NAME, same flags -- so the CLI and the installer agree on what
"installed" means. install/remove need admin (a boot trigger touches
system-wide scheduler state); status/run/end do not, once the task exists,
because Task Scheduler grants the owning user that much by default -- which
is what lets the Node page's Start/Stop/Restart drive it with no further
UAC prompts.
Shipped as an extraResource at <install>\resources\service.ps1, so it
locates meshbay-node.exe from its own path.
.PARAMETER Action
install | remove | status | run | end
#>
[CmdletBinding()]
param(
[ValidateSet("install", "remove", "status", "run", "end")]
[string]$Action = "status"
)
# Not "Stop": schtasks writes its normal "task not found" outcome to stderr,
# and with ErrorActionPreference=Stop that promotes to a terminating error
# even through a 2>$null redirect (a native command's stderr is converted to
# an ErrorRecord before the redirect discards it). Every exit path below
# checks $LASTEXITCODE explicitly instead.
$TASK_NAME = "MeshBay Node"
$resources = $PSScriptRoot
$node = Join-Path $resources "node-runtime\meshbay-node.exe"
function Get-CurrentUser {
$domain = $env:USERDOMAIN
if (-not $domain) { $domain = $env:COMPUTERNAME }
return "$domain\$env:USERNAME"
}
switch ($Action) {
"install" {
if (-not (Test-Path $node)) { throw "meshbay-node.exe not found at $node" }
$user = Get-CurrentUser
# NOT $action: PowerShell variable names are case-insensitive, so $action
# is this script's own [ValidateSet("install",...)][string]$Action
# parameter. Assigning the New-ScheduledTaskAction CimInstance to it
# runs the ValidateSet check (fails) and coerces the object to the
# string "MSFT_TaskExecAction", which Register-ScheduledTask -Action
# then rejects with "MSFT_TaskExecAction is not a valid value for the
# Action variable" -- the install path never actually created the task.
$taskAction = New-ScheduledTaskAction -Execute $node
$bootTrigger = New-ScheduledTaskTrigger -AtStartup
$taskPrincipal = New-ScheduledTaskPrincipal -UserId $user -LogonType S4U -RunLevel Limited
Register-ScheduledTask -TaskName $TASK_NAME -Action $taskAction -Trigger $bootTrigger `
-Principal $taskPrincipal -Force -ErrorAction Stop | Out-Null
Write-Host "service: installed ($user, runs at boot)"
}
"remove" {
& schtasks /delete /tn $TASK_NAME /f 2>$null | Out-Null
Write-Host "service: removed"
}
"status" {
$out = & schtasks /query /tn $TASK_NAME /fo list 2>$null
if ($LASTEXITCODE -ne 0) {
Write-Output "NOT_INSTALLED"
exit 1
}
$line = $out | Select-String "^Status:"
$state = if ($line) { ($line -replace "^Status:\s*", "").Trim() } else { "unknown" }
Write-Output "INSTALLED:$state"
exit 0
}
"run" {
& schtasks /run /tn $TASK_NAME
if ($LASTEXITCODE -ne 0) { throw "schtasks /run failed (exit $LASTEXITCODE)" }
}
"end" {
& schtasks /end /tn $TASK_NAME
if ($LASTEXITCODE -ne 0) { throw "schtasks /end failed (exit $LASTEXITCODE)" }
}
}
|