Windows nodes
install-agent.ps1 installs the node agent on a Windows 11 PC with an NVIDIA GPU (P4, design-p3p4 §A.4) and the
pinned llama.cpp runtime (§A.1.2). It runs in an elevated Windows PowerShell 5.1 window (the default shell) or in
PowerShell 7. Docker Desktop is not needed: models run as native llama-server processes under the service account.
Before you start
Section titled “Before you start”- An NVIDIA driver at or above the lock file’s
minDriver(615.00forb11476, CUDA 13.4). Check withnvidia-smi --query-gpu=driver_version --format=csv,noheader. - The Microsoft Visual C++ 2015-2022 Redistributable (x64). The llama.cpp binaries import
msvcp140.dll,vcruntime140.dllandvcruntime140_1.dll, and the release zips do not include them. The installer checksSystem32and stops if one is missing. It never downloads the redistributable itself; install it from Microsoft. - The clock in sync (
w32tm /query /status), and the PC set never to sleep on AC power. The installer warns about both.
Join a node
Section titled “Join a node”Use the “Add node” command on the master’s Nodes page. It downloads the win-x64 bundle, checks its SHA-256 and
runs this script:
$env:MIRBADLLM_JOIN_TOKEN = '<token>'.\install-agent.ps1 install -NodeId win-1 -EnrollUrl https://<master>:8443 -CaHash sha256:<hash> -LlamaCppTo keep the token out of the window altogether, leave out the first line and add -PromptToken. The script then
reads the token with Read-Host -AsSecureString. The token never goes in a parameter, because every user can read
process command lines. The script clears it in a finally block, so it is removed even when a step fails.
install does this:
- Copies
mirbadllm-agent.exetoC:\Program Files\mirbadllm-agent\app\{version}\. - Creates the service
mirbadllm-agentunder the virtual accountNT SERVICE\mirbadllm-agent, with startup type Automatic (Delayed Start) and restart on failure. - Writes
%ProgramData%\mirbadllm-agent\agent.jsononce, fromagent.windows.example.json. Only SYSTEM, Administrators and the account can read that folder: its root is protected and everything below it inherits. - Sets the service’s
PreshutdownTimeouttoAgent:ShutdownTimeout+ 10 s, so Windows waits for the agent to drain before it shuts down, and registers the Event Log sourcemirbadllm-agentin the Application log. The virtual account cannot create that source itself. - Enrolls the node.
- With
-LlamaCpp, installs llama.cpp (see below). - Opens TCP 9443 inbound for the service only. The rule covers the Private profile only and allows only the master, by default the enroll URL’s host. It warns in red when the Windows Firewall is off.
- Starts the service. Use
-NoStartto skip this.
Running install again upgrades the binary in place and keeps agent.json and the identity.
llama.cpp
Section titled “llama.cpp”.\install-agent.ps1 -LlamaCpp # the version pinned in llama-cpp.lock.json (b11476).\install-agent.ps1 -LlamaCpp b11476 -LlamaCppSource D:\downloads # zips already downloaded.\install-agent.ps1 -RemoveLlamaCpp b11476-LlamaCpp takes these steps:
- Refuses a driver below
minDriver, and a PC without the VC++ runtime. - Downloads both release assets by tag. It never uses
releases/latest, because everybNNNNrelease is a prerelease. - Checks each zip’s size and SHA-256.
- Unpacks both zips into one staging folder.
- Requires exactly the lock file’s 55 files: each one present with the right size and hash, none missing, none extra. A planted DLL would otherwise load from the application folder first.
- Moves the folder to
C:\Program Files\mirbadllm-agent\runtimes\llama.cpp\b11476\, read-only for the account. - Writes
manifest.jsonthere and adds theAgent:Executablesentry toagent.json.
If the folder is already installed and verifies, it is kept as it is; if it fails verification, it is installed
again. A running service is restarted so it picks up the change; running models keep running and are adopted again.
-RemoveLlamaCpp is refused while a process runs from that folder. It is also refused while that version is the
default of other installed versions.
Upgrade, rollback, rekey, uninstall
Section titled “Upgrade, rollback, rekey, uninstall”An agent installed before the project’s rename is upgraded in place and keeps its old service and folder names; see “Upgrading from a pre-rename install” in docs/setup.md.
.\install-agent.ps1 upgrade -Bundle .\win-x64.zip -BundleSha256 <hex> # or -PublishedDir, or run from the bundle.\install-agent.ps1 rollback$env:MIRBADLLM_JOIN_TOKEN = '<rekey token>'.\install-agent.ps1 rekey -EnrollUrl https://<master>:8443 -CaHash sha256:<hash> [-NodeUid <uid>].\install-agent.ps1 uninstall- upgrade installs the new version next to the current one and stops the service. It switches the service’s
binPathto the new folder, starts it, and waits until it listens on 127.0.0.1:9443. If the new version does not come up, it switches back and starts the previous version.llama-serverprocesses keep running throughout. The last three agent versions are kept. - rollback switches back to the previous version.
- rekey stops the service and keeps a copy of
agent.crt,agent.key,ca.crtandnode-uid. It then runsmirbadllm-agent.exe join --rekey, re-applies the private ACL and starts the service. If the rekey fails, it restores exactly the saved identity and starts it again. - uninstall stops only the runtime processes that the service account started from the runtimes folder. It
removes the service, its Event Log source, the firewall rule and
C:\Program Files\mirbadllm-agent, and keeps%ProgramData%\mirbadllm-agent. It then prints the command that removes the account’s profile after a reboot.
Importing a GGUF by hand
Section titled “Importing a GGUF by hand”.\install-agent.ps1 -ImportGguf C:\Users\me\.ollama\models\blobs\sha256-<hex> -Folder plannerThis copies the file into {ModelsRoot}\planner\model.gguf and checks its SHA-256. For an Ollama blob, the hash is
taken from the blob’s name; for any other file, pass -Sha256. It is a manual fallback only. The designed path is
the agent’s own download.
Dry run and tests
Section titled “Dry run and tests”-DryRun runs every check (the llama.cpp download and its verification run in a temporary folder) and prints each
change without making it. The Pester suite in test\ drives the script’s own functions against temporary folders,
with the service, driver, port and enrollment calls faked. It runs under Pester 3.4 (inbox) and 5.x:
powershell.exe -NoProfile -Command "Invoke-Pester deploy\agent\windows\test"The xUnit test WindowsInstallerTests runs that suite under Windows PowerShell 5.1, together with the ACL and parse
checks.
