Skip to content

Fleet Deployment

Iain Smith edited this page Aug 29, 2026 · 6 revisions

Fleet Deployment

Running loadbearer unattended across a managed Windows estate — with PDQ Deploy / PDQ Inventory, Intune, ConfigMgr, or a GPO startup script — and collecting the result files centrally. The guidance is written for PDQ but the shape is the same everywhere.

loadbearer is a good fit for this: one self-contained .exe, no installer, no runtime, no registry writes, no persistence, no service, and it never launches a child process or makes a network call (unless you explicitly pass --net-target).

The deploy step

Install step → Run Command:

loadbearer.exe run --no-gpu --plain --duration short ^
  --target-dir "%ProgramData%\loadbearer" ^
  --output "%ProgramData%\loadbearer\%COMPUTERNAME%.json"

Then a Pull File step for %ProgramData%\loadbearer\%COMPUTERNAME%.json into a share, and a cleanup step (below).

Set the step timeout to at least 300 s — a short run is ~40 s of work, but a slow or busy machine, plus the disk benchmark's scratch-file fill, can take longer, and a step that times out mid-run leaves a scratch file behind.

Why each flag

Flag Why
--no-gpu Skips the GPU component and the OpenCL probe. Without it, every run (and loadbearer info) dlopens OpenCL.dll and enumerates devices; a stale ICD loader left behind by an uninstalled GPU driver can stall that. GPU is not in the grade anyway.
--plain Forces the plain-text report. It's implied when there's no console (PDQ runs as SYSTEM with redirected output), but pass it so a run through PsExec-with-console doesn't try to open the TUI. Use --json instead if you want to parse stdout directly.
--target-dir "%ProgramData%\loadbearer" Always set this. The default is the working directory, which under PDQ is a temp path you didn't choose — so the 1 GiB disk-benchmark scratch file lands somewhere arbitrary, and it measures that volume. Point it at the volume you want the disk numbers for (usually C:).
--duration short ~40 s total. normal is ~2½ min, thorough ~10 min — too long for a fleet sweep.
--output ...\%COMPUTERNAME%.json Writes the full versioned result (loadbearer.result/1) — machine inventory, every raw metric, the scored grade — for the Pull File step. Distinct filename per host.

The workload seed is fixed by default, so every machine runs the exact same benchmark and the results are directly comparable. Don't pass --seed unless you have a reason to.

Exit codes

loadbearer exits 0 on success and non-zero on any failure (unreadable config, unwritable --output, a benchmark error). PDQ marks the step failed on non-zero, so a failed sweep on a subset of machines is visible without parsing output. A panic (very unlikely in the graded CPU / memory / disk path) aborts the process — PDQ still sees a failure.

The scratch file

The disk benchmark creates .loadbearer-scratch.<pid> in --target-dir (1 GiB at normal, ~512 MiB at short), reuses it for every disk subtest, and deletes it on a normal exit. A step that is killed — PDQ timeout, TerminateProcess, machine reboot — leaves it behind. Add a cleanup step to the package:

del /q "%ProgramData%\loadbearer\.loadbearer-scratch.*" 2>nul

The unsigned binary

The released .exe is not Authenticode-signed. On a machine with WDAC or AppLocker enforced, add a file-hash allow rule for loadbearer.exe — hash rules permit an unsigned binary; publisher rules don't. Take the hash from the SHA256SUMS file on the release page (it lists the bare loadbearer.exe hash, not just the archive) or from Get-FileHash loadbearer.exe.

SmartScreen shows an "unrecognized app" prompt for interactive launches; it does not block a SYSTEM-context deploy.

The release workflow Authenticode-signs the binary automatically if the repository is configured with a code-signing certificate (WINDOWS_PFX_BASE64 / WINDOWS_PFX_PASSWORD secrets) — otherwise build from source and sign with your own cert.

Do not put these in a package

Command Why not
loadbearer net-server Binds 0.0.0.0:47913 and listens forever — it's the server half of the manual link test, not a fleet task.
loadbearer run --net-target HOST:PORT Makes an outbound connection to another host. Fine for a deliberate two-machine link test, wrong for a broadcast deploy.
loadbearer soak / run --soak Pins every core for 60–120 s. Useful on a single laptop you're assessing; a fleet-wide thermal event is not.

Collecting the results

Once the .json files are in a share, treat them as a corpus:

# rank a fleet, or diff a refresh candidate against the incumbents
loadbearer compare fleet\*.json

# just the headline per machine
jq -r '[.machine.hostname, .overall.score, .overall.grade] | @tsv' fleet\*.json

# build a house baseline from the machines you consider "par", then
# re-grade everything against it without re-running anything
loadbearer baseline fleet\dell-7420-*.json --name our-standard > our-standard.toml
for f in fleet\*.json; do loadbearer score "$f" --baseline our-standard.toml --json; done

The result files keep the full raw metrics, so they can be re-scored against a new baseline or curve at any time (see The Baseline) — you don't need to redeploy to change how the fleet is graded.

What a run touches

  • Writes: the scratch file and the --output file, both under --target-dir. Nothing else on disk, nothing in the registry.
  • Network: none. The network component is loopback (127.0.0.1) only.
  • Privilege: none required. Runs fine as a standard user or as SYSTEM.
  • Processes: none spawned.
  • Persistence: none. It runs and exits.

Clone this wiki locally