Skip to main content

Agent

rmm-agent.exe is a Go program that runs as the Windows service RMMAgent (LocalSystem). Source: entrosity-axis-agent/, with the transport, executor, secret store, logging, service wrapper and updater shared with the connector in entrosity-shared-go/agentkit.

Installation​

The MSI (entrosity-axis-agent/installer/Package.wxs, WiX v4) installs the service and enrolls in one step:

msiexec /i rmm-agent.msi /qn ENROLLMENT_TOKEN=<token> SERVER_URL=<url>
PropertyMeaning
ENROLLMENT_TOKENAgent enrollment token (hidden from logs).
SERVER_URLThe server's public URL.

A failed enrollment rolls the install back. Without the properties, the service waits until rmm-agent.exe enroll is run. Upgrades use WiX MajorUpgrade, and downgrades are allowed (the self-update rollback needs them).

Command line​

rmm-agent <command> [flags]

run run the agent (foreground, or as a service under the SCM)
--server URL --token T enroll first if not enrolled yet
enroll enroll this machine: --server URL --token T [--force]
inventory collect the inventory and print it: [--json] [--delta]
status show enrollment state
install install the Windows service
uninstall remove the Windows service
version print the version

RMM_DATA_DIR overrides the data directory. inventory works without a server, which is useful when working on collectors.

Files​

%ProgramData%\RMM\
agent.dat DPAPI-encrypted (machine scope) {agent_id, agent_key, server_url}
config.json last config from the server
state.json pending / in-progress job ids (+ detection metadata) for crash recovery
logons.json sign-outs not yet delivered to the server (at most 256)
cache\ downloaded packages by SHA-256 (LRU, 2 GiB cap, .verified marker)
update\ self-update MSIs, update.ps1, result.json
logs\agent.log rotating log
logs\remote-helper.log remote desktop capture helper (emptied above 5 MiB)
logs\user-notice.log restart/shutdown notices shown to users

Warnings and errors also go to the Application event log (source RMMAgent).

Behaviour​

WhatWhen
Heartbeat (CPU, memory, disks, logged-on user, uptime, pending reboot, CPU temperature)Every 60 s
Full inventoryAt start and every 24 h
Delta inventory (software, disks, services)Every 4 h
ReconnectExponential back-off 1 s → 5 min with 20 % jitter
HTTP polling fallbackAfter 10 failed WebSocket attempts, every 5 min, while retrying the WebSocket in the background

The server can change the intervals with config.update.

Inventory collectors​

System (OS, hardware, last boot, user), software (registry, machine and per-user; winget IDs added when winget is present), disks, network adapters, services, Windows updates and local users. A collector that fails is reported in errors[] and its section is left untouched on the server.

Jobs​

inventory, install_package, uninstall_package, run_script, reboot, shutdown, update_agent, winget_search, remote_desktop. Jobs run one at a time, except remote_desktop, which has a lane of its own so a consent prompt waiting for an answer does not hold up other jobs. Before executing, the agent records the job in state.json; if it crashes or restarts, it reports each leftover job on start (succeeded if detection shows the intended state, otherwise agent_restarted).

Details: Protocol.

Capabilities​

The agent announces winget (when winget is available), run_as_user (Windows) and remote_desktop (Windows) in its hello. Agents before 0.5 answer run_as_unsupported to run-as-user jobs; the server refuses remote desktop sessions for agents without remote_desktop (remote_unsupported).

Sign-ins​

Every 10 seconds the agent lists the Windows sessions (WTSEnumerateSessions, skipping session 0 and sessions without a user) and identifies each sign-in by session id and logon time. It sends a session.report on every change, on every (re)connect and at least every 15 minutes. Sign-outs it could not deliver are kept in logons.json and sent with the next report. Remote Desktop sign-ins carry the client's name or address. See Sign-ins.

CPU temperature​

Each heartbeat carries the hottest thermal zone in °C (rounded to 0.1), read through the Windows performance counters (\Thermal Zone Information(*)\Temperature, the same ACPI data as WMI's MSAcpi_ThermalZoneTemperature) with one query kept open for the agent's lifetime, so no process starts per heartbeat. Implausible readings (0 K, outside -40..150 °C) are dropped; without a usable sensor, common on virtual machines, the heartbeat has no temperature and the agent tries the counters again after an hour.

User notices​

Before a reboot or shutdown (device actions and package reboot policies), the agent shows every signed-in user a notice in the product's design: it starts rmm-agent.exe notice --kind=<restart|shutdown> --deadline=<unix seconds> --message=<text> in each active session (SYSTEM token moved to the session, like the remote desktop helper), right after shutdown.exe accepted the restart. The notice counts down to the deadline, closes on Dismiss and quits by itself 10 minutes after the deadline. A notice that cannot be shown is logged and never fails the job. It replaces the plain msg.exe box of earlier agents. notice is internal and not listed in the usage text.

Remote desktop​

A remote_desktop job (Remote desktop) is handled like this:

  1. Consent. When the job asks for it and a user is signed in to the console session, the service starts rmm-agent.exe remote-consent --viewer=<technician> --mode=<mode> --timeout=60 in that session (same token and desktop as the helper below). It shows the Remote support request window (Entrosity design, Decline focused, Allow, countdown) and answers with its exit code: 20 allowed, 21 declined, 22 timed out. Anything but 20, including a crash, fails the job with remote_declined; a consent window that cannot be started at all is remote_unavailable. A locked session is declined at once (the user cannot answer). remote-consent is internal and not listed in the usage text.
  2. Helper. The service (LocalSystem, session 0) cannot see the desktop, so it starts rmm-agent.exe remote-helper --mode=<mode> --viewer=<technician> --banner=<true|false> in the active console session (or the first active session) on winsta0\default, with a copy of its own SYSTEM token moved to that session. Running as SYSTEM lets the helper follow the input desktop: the sign-in and lock screens and UAC prompts are captured and controllable. The helper talks to the service over its standard input and output (4-byte length, 1-byte kind, payload) and inherits no other handles; it logs to logs\remote-helper.log in the data directory (emptied when it is over 5 MiB). remote-helper is internal and not listed in the usage text.
  3. Stream. The service opens wss://<server>/api/agent/v1/remote/<session_id> with its agent key and relays between the helper and the server. The job succeeds (remote session started) and the stream carries on until either side closes it; the helper is then stopped. Failures before that are remote_unavailable.

The helper is per-monitor DPI aware and captures with GDI (BitBlt of the composed desktop, with the cursor drawn in) at up to 15 frames per second, sending changed 64×64 tiles as JPEG. Input uses SendInput: absolute pointer coordinates over the whole virtual desktop, keys by scan code (so the device's keyboard layout applies) and typed text as Unicode. View-only sessions ignore input in the helper too.

Unless the job sets hide_banner (administrators only; --banner=false), the helper also shows the user a bar in the portal's style (logo, green dot, is controlling your screen or viewing, and a red End session button) on its own thread on the normal desktop. End session makes the helper exit with code 11, and the service closes the stream with 4000 the user ended the session.

Capture errors while Windows switches desktops (lock screen, UAC, Ctrl+Alt+Del) are retried with back-off; only 15 s of continuous failure ends the session. When the console session changes (sign-out, fast user switching, RDP taking the console), the helper exits with code 10 and the service starts a new one in the new session on the same stream, at most 5 times a minute; a newly signed-in user is asked for consent again when the session required it. Any other helper exit closes the stream with 4004.

A device has one session at a time: a new session stops the previous one.

Ctrl+Alt+Del

The Ctrl+Alt+Del button calls SendSAS, which Windows allows only when the Disable or enable software Secure Attention Sequence policy (HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System, SoftwareSASGeneration) is set to Services (1) or Services and Ease of Access applications (3). Otherwise the technician sees an error; set the policy with Group Policy where it is needed. The agent checks the policy first and reports Ctrl+Alt+Del is blocked by policy when it is not set.

Development builds on macOS and Linux​

The agent builds and runs on macOS and Linux for development:

go run ./agent/cmd/rmm-agent run --server http://localhost:8080 --token <token>

Collectors report a stub summary and credentials are stored unencrypted in ~/.rmm-agent (override with RMM_DATA_DIR).