Add a Windows agent (PowerShell)
Reports a Windows machine the way the Linux agent does, replacing the
"planned" stub in agent/windows: scheduled tasks plus hostname, IPv4
addresses, CPU model/cores/current load, memory, every fixed disk, and
TCP/UDP listening ports with the owning process (which feed the Ports
card, localhost-only listeners included).
Scripts (plain ASCII by design -- they are downloaded as text and Windows
PowerShell 5.1 reads BOM-less files as ANSI):
- report-tasks.ps1: collects and POSTs to /api/agent/report. Works in
Windows PowerShell 5.1 and PowerShell 7. -DryRun prints the JSON.
Microsoft's own \Microsoft\ tasks (hundreds) are left out unless
INCLUDE_MICROSOFT_TASKS is set. Triggers are turned into readable text
("Weekly on Mon, Wed at 03:00", "At logon", "..., repeating every 15 min").
Self-signed certificates work via API_INSECURE on both PowerShell
versions (they need different mechanisms).
- install.ps1: elevated only; downloads the agent to ProgramData, writes
agent.json with permissions locked to SYSTEM and Administrators *before*
the token goes in, and registers a SYSTEM scheduled task (every 15 min
plus at startup with a 2 min delay). Reinstalling replaces the task.
- uninstall.ps1: removes the task and only the files the agent installed.
Server: accepts schedule_type "windows_task"; a server can be registered
as Windows (Add a server has an operating system choice); an agent's
reported os_type ("linux"/"windows", anything else ignored) corrects the
stored one. The Servers page shows the right install and uninstall
command for each OS (Windows PowerShell 5.1 one-liners, with a self-signed
variant and a note about PowerShell 7), and Windows tasks are labelled
"Windows scheduled tasks". The Linux commands are unchanged.
Verified on this Windows machine, in both PowerShell 5.1 and 7:
- Real dry runs found and fixed bugs before anything shipped: tasks and
ports came out as one nested item (return , $out wrapped twice), integer
keys in an ordered dictionary index by position (wrong weekday names),
and generic "Trigger" labels.
- End to end against the real agent-report router: HTTP, self-signed HTTPS
refused by default and accepted with API_INSECURE, wrong token gives a
clear one-line error and exit 1, and Swedish letters plus a euro sign
survive JSON -> UTF-8 -> HTTP -> SQLite.
- 35 checks on trigger/action/duration descriptions, 20 on the installer's
building blocks (task parts built but not registered, credentials file
content and ACL, download over HTTP and self-signed HTTPS), 18 on the
server rules, and the generated one-liners run through PowerShell's
parser. The documented one-liners were run through iex and stop at the
administrator check without changing anything.
- Found that PowerShell 7 ignores the ServicePointManager certificate
override, so the installer's own download now uses -SkipCertificateCheck
there.
NOT verified: the elevated install itself. Registering a SYSTEM scheduled
task needs elevation and changes the machine, so it was not run: the task
registration, that the repeating trigger really runs indefinitely, and
the agent running as SYSTEM under Task Scheduler have not been exercised.
Windows 10 / Server 2016 or newer is assumed; older is untested.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ae64cb345c
commit
fea20456e4
14 files changed
+675
-43
No files matched your search
@@ -0,0 +1,46 @@
|
||||
# Removes the Homelab Manager agent from this Windows machine: deletes its scheduled task, the installed
|
||||
# script, and its credentials file.
|
||||
#
|
||||
# Run in an ELEVATED Windows PowerShell (Run as administrator):
|
||||
#
|
||||
# [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
# iex ((New-Object Net.WebClient).DownloadString('https://homelab.example.lan/agent/windows/uninstall.ps1'))
|
||||
#
|
||||
# (With a self-signed certificate, also run
|
||||
# [Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
|
||||
# first.)
|
||||
#
|
||||
# NOTE: keep this file plain ASCII (it is downloaded as text).
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
$script:TaskName = 'Homelab Manager Agent'
|
||||
$script:InstallDir = Join-Path $env:ProgramData 'HomelabManager'
|
||||
|
||||
function Uninstall-Agent {
|
||||
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
|
||||
if (-not ([Security.Principal.WindowsPrincipal]$identity).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
|
||||
throw 'This uninstaller must be run as Administrator. Open PowerShell with "Run as administrator" and try again.'
|
||||
}
|
||||
|
||||
Write-Output 'Removing Homelab Manager agent...'
|
||||
|
||||
if (Get-ScheduledTask -TaskName $script:TaskName -ErrorAction SilentlyContinue) {
|
||||
Stop-ScheduledTask -TaskName $script:TaskName -ErrorAction SilentlyContinue
|
||||
Unregister-ScheduledTask -TaskName $script:TaskName -Confirm:$false
|
||||
}
|
||||
|
||||
# Only the files this agent installed - never the folder wholesale, in case something else was put beside them.
|
||||
foreach ($name in 'homelab-manager-agent.ps1', 'agent.json') {
|
||||
$path = Join-Path $script:InstallDir $name
|
||||
if (Test-Path -LiteralPath $path) { [System.IO.File]::Delete($path) }
|
||||
}
|
||||
if ((Test-Path -LiteralPath $script:InstallDir) -and -not (Get-ChildItem -LiteralPath $script:InstallDir -Force)) {
|
||||
[System.IO.Directory]::Delete($script:InstallDir)
|
||||
}
|
||||
|
||||
Write-Output 'Done. The agent no longer runs or reports from this machine.'
|
||||
Write-Output 'Its entry (and task history) in Homelab Manager is untouched - delete it from the Servers page if you no longer want it tracked.'
|
||||
}
|
||||
|
||||
Uninstall-Agent
|
||||
Reference in new issue
Block a user