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
|
<#
.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.
`schtasks /create ... /ru <user> /rp ""` with no `/it` registers 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.
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
& schtasks /create /tn $TASK_NAME /tr "`"$node`"" /sc onstart /ru $user /rp "" /rl limited /f
if ($LASTEXITCODE -ne 0) { throw "schtasks /create failed (exit $LASTEXITCODE)" }
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)" }
}
}
|