Inventory
The Hermes agent discovers hardware, software and configuration on each Windows and Linux endpoint and reports it to the server. Inventory is organized into modules. The agent keeps its own copy of the last collection and, after the first report, sends a module again only when its content has changed.
What's collected#
Each module covers one area of the endpoint. Not every module exists on both platforms. The linked pages describe what each area shows on the agent details page.
| Module | What it covers | Windows | Linux |
|---|---|---|---|
os | Operating system: name, edition, version, build, architecture, domain | Yes | Yes |
hardware | Hardware: manufacturer, model, serial, chassis, BIOS, virtual-machine detection | Yes | Yes |
bootsecurity | Boot & security: Secure Boot, TPM, pending restart | Yes | Yes |
processors | Installed CPUs (see Hardware) | Yes | Yes |
memory | Memory and per-slot detail | Yes | Yes |
storage | Volumes and storage devices (see Hardware) | Yes | Yes |
physicaldisks | Physical disks & disk health | Yes | Yes |
network | Network configuration and interfaces | Yes | Yes |
shares | Shared folders exposed by the endpoint | Yes | Yes |
software | Installed software | Yes | Yes |
services | Services and their state | Yes | Yes |
environment | Environment variables | Yes | Yes |
localgroups | Local groups and membership | Yes | Yes |
updates | Installed hotfixes / KB updates (see Windows Updates) | Yes | — |
missingupdates | Updates the endpoint is missing, checked against the offline update catalog (see Windows Updates). Included only when the agent has a catalog. | Yes | — |
features | Windows optional features that are enabled | Yes | — |
virtualization | Virtualization host inventory | Yes | — |
containers | Container inventory | — | Yes |
rustdesk | RustDesk remote-support client state | Yes | Yes |
agentinfo | The agent itself: hostname, agent version and similar details | Yes | Yes |
metrics | Real-time CPU, memory and disk metrics | Yes | Yes |
On Windows, inventory is read mainly from WMI and the registry. CPU usage in the real-time metrics comes from performance counters. Modules are collected in parallel and each one is handled as soon as it finishes. A module that fails to collect is skipped for that pass and doesn't block the others.
How inventory reaches the server#
Collecting inventory and sending it are separate steps. The agent collects into a local copy on the endpoint. It then sends the server only the modules that the server doesn't already have in their current form.
- On connect. When the agent connects to a server, it sends its stored inventory right away and doesn't collect again first. On a fresh install with nothing stored yet, it runs a full collection first and then sends the result.
- Periodic full collection. Every Full Inventory Interval (see Refresh intervals) the agent collects every module again and updates its local copy. This step on its own sends nothing to the server.
- Changes only. At the heartbeat cadence, the agent compares each stored module with what it last sent to each connected server. It sends a module only if the module has changed. A changed module is sent in full. An endpoint where nothing changed sends no inventory traffic between collections.
- Metrics are not part of this comparison. They travel with every heartbeat.
Commands have priority over inventory. If a command is running when a periodic collection is due, the agent skips that collection and tries again at the next interval. If a command starts during a collection, the agent stops collecting for that pass.
An agent that reports to more than one server (see Multi-Homed Agents) collects once and tracks what it has sent to each server separately. Each time a server connection is re-established, the agent sends that server its full stored inventory again.
Because of this design, the data you see is at most one Full Inventory Interval (plus one heartbeat) old. If you need current data immediately, use Collect inventory now.
Agent properties derived from inventory#
As modules arrive, the server updates a few properties on the agent record. You can use these properties in filters and dynamic collections:
| Filter field | Set from | Meaning |
|---|---|---|
IsServer | os | The endpoint runs a server edition of its operating system. |
IsDomainJoined | os | The reported domain is set and isn't WORKGROUP. |
DomainName | os | The domain (or workgroup) the endpoint reports. |
IsVirtualMachine | hardware | The endpoint is a virtual machine. |
ChassisType | hardware | The reported physical form factor. |
IsLaptop | hardware | Chassis type is Laptop, Notebook or Portable. |
IsTablet | hardware | Chassis type is Tablet. |
IsSFF | hardware | Chassis type is Small Form Factor, Mini Tower or Compact. |
Querying inventory#
GET api/agents/{agentId}/inventory returns everything the server holds for an
agent. Sub-routes return a single area:
| Sub-route | Returns |
|---|---|
.../inventory/os | Operating system inventory |
.../inventory/hardware | Hardware inventory |
.../inventory/metrics | Real-time CPU / memory / disk metrics |
.../inventory/processors | Processor inventory |
.../inventory/memory | Memory slot inventory |
.../inventory/storage | Storage devices |
.../inventory/network | Network configuration and interfaces |
.../inventory/software | Installed software |
.../inventory/updates | Installed hotfixes / KBs |
.../inventory/services | Windows services |
.../inventory/features | Windows optional features |
Areas without their own sub-route, such as shares, local groups or environment variables, are
included in the full GET api/agents/{agentId}/inventory response. All of these routes need the
inventory.view permission, which the built-in Helpdesk,
Operator and Admin roles include (see
Permission Model). They return 404 when the
agent doesn't exist or hasn't reported that area yet, and 403 without the permission.
These routes return what the server already holds. To make an agent collect fresh data first, use Collect inventory now. Fetch the hardware inventory for an agent over the API:
# Fetch hardware inventory for one agent
$headers = @{ Authorization = "Bearer $token" }
Invoke-RestMethod `
-Uri "https://athena.example.com:8443/api/agents/$agentId/inventory/hardware" `
-Headers $headers `
-SkipCertificateCheck
Collect inventory now#
Agents report inventory on their own schedule. When you need current data right away, for example after installing software, changing hardware or fixing a configuration, use Collect inventory. The agent runs a fresh, full collection of every module. It does not resend the snapshot it already has. This works on both Windows and Linux agents.
Where to start it
| Where | Control | Targets |
|---|---|---|
| Agent details header | The Collect inventory icon button (tooltip: Collect inventory now - the agent runs a fresh full collection) | This one agent. The button is also shown while the agent is offline, so a click tells you the agent is offline instead of the button disappearing. |
| Agents list | Tick the row checkboxes, then click Collect inventory (n) in the toolbar | The selected agents. The header checkbox selects every agent on the current page. |
| Collection details page | Collect Inventory | Every current member of the collection. The button is disabled when the collection has no members. It is also available on system-managed collections. |
The Agents list clears your selection when you change page, filter or search, so Athena never acts on agents you can no longer see. The same selection also drives Restart.
Who can use it
Collecting inventory requires the agents.manage permission. The built-in
Operator and Admin roles include it (see
Permission Model). Users without it do not see the button,
the Agents-list checkboxes or the collection button. The REST API returns 403 to them.
What you see
Athena sends the request to each agent that is connected right now. Nothing is queued for offline agents, so run the request again once they are back online. Every targeted agent gets one of these outcomes:
| Outcome | Meaning |
|---|---|
Sent | The agent received the request. Its fresh inventory arrives shortly after. |
Offline | The agent is not connected to this server. Nothing was sent. |
Failed | The agent was connected, but the request could not be delivered. |
NotFound | No agent exists with that ID (REST API only). |
- Single agent: a toast reads Inventory requested - the page updates as the agent reports, Agent is offline - inventory was not requested, or Could not send the inventory request to the agent.
- Agents list or collection: a toast reads Inventory requested from x of y agents (z offline). If no agent received the request, it is shown as a warning.
- On the agent details page, the Last Inventory card (Most recent module received) and the inventory sections update live as each module arrives. You don't need to reload the page.
Collect inventory vs. the refresh button vs. Scan for Missing Updates. The plain refresh button next to Collect inventory only reloads what the server already holds. It does not contact the agent. Collect inventory does not make the agent download the WSUS update catalog. An agent that already has a cached catalog still checks for missing updates as part of the collection. To send the current catalog and force an update scan, use Scan for Missing Updates in the agent's Windows Updates section (see Windows Update Management). After a restart from Athena, a full collection is requested automatically when the agent reconnects.
REST API
| Endpoint | Body | Responses |
|---|---|---|
POST api/agents/{id}/inventory/refresh | None | 200 request delivered · 404 no such agent · 409 agent offline or send failed (nothing collected) · 403 missing agents.manage |
POST api/agents/inventory/refresh | agentIds (array of agent IDs) and/or collectionId. Athena uses the combination of both, with duplicates removed. | 200 with per-agent outcomes (offline agents are reported, not an error) · 400 no agents to collect from · 404 collection not found · 403 missing agents.manage |
Both return the totals totalRequested, sentCount,
offlineCount and failedCount (failed plus not found), and a
results array of { agentId, hostname, status }. The inventory itself
arrives asynchronously. Read it afterwards with the inventory routes.
# Collect fresh inventory from every member of a collection
$headers = @{ Authorization = "Bearer $token" }
$body = @{ collectionId = $collectionId } | ConvertTo-Json
$r = Invoke-RestMethod -Method Post `
-Uri "https://athena.example.com:8443/api/agents/inventory/refresh" `
-Headers $headers -ContentType "application/json" -Body $body `
-SkipCertificateCheck
$r.data.results | Where-Object status -ne "Sent" # who still needs a retry
Auditing
Each request writes one InventoryRefreshRequested event to the
audit log. It records who asked and lists the hostnames that were
sent the request, offline, failed or not found. The action is CollectInventory,
or UpdateScan when the collection came from Scan for Missing Updates.
Refresh intervals#
Two fleet-wide settings control how fresh inventory is. You set both on Settings → Agents (see Agent Settings, which also lists their defaults). The server pushes changes to connected agents.
| Setting | Effect on inventory |
|---|---|
Heartbeat IntervalheartbeatIntervalSeconds | How often the agent checks in. Changed modules and real-time metrics are sent at this cadence. |
Full Inventory IntervalstatusUpdateIntervalSeconds | How often the agent runs a full collection of every module. This is the heavier operation. Shorter intervals give fresher data but put more load on the endpoints. |