IPMI
Read one IPMI value from a BMC and check it, or write one. A step names what it reads with get (a sensor, a FRU field, a SEL entry, or a field of a decoded IPMI command), writes a value with set, sends request bytes with raw, or captures the host console with sol, and states what it expects with expect, the same way Shell pairs command with expect. The step runs ipmitool, in-band on the transport target or over lanplus, and reports each check with the value it found.
| Attribute | Type | Required | Default | Description |
|---|---|---|---|---|
cmd | const | Yes | ipmi | Command Name |
name | string | Yes | Name to uniquely identify the teststep. This name will show up in reports, logs and the WebUI | |
transport | TransportObject | No | local | Where ipmitool runs. See IPMI Transport. |
options | OptionsObject | No | Additional command options. The default timeout is 2 minutes. | |
parameters | IPMIOptions | Yes | Options passed into the ipmi cmd |
IPMI Quick start
Check a sensor reading, running ipmitool on the BMC itself:
Check the watchdog over lanplus from the runner:
Each step reads one thing. To check several values, use several steps; a failure then names exactly what broke.
IPMI Options
Exactly one of get, set, raw and sol is required.
| Attribute | Type | Required | Default | Description |
|---|---|---|---|---|
get | string | Conditional | What to read. See IPMI Paths. | |
set | string | Conditional | What to write, with value. See IPMI Set. | |
value | scalar or map | With set | The value set writes: a name or its number, such as cycle or 0x02, or the fields of a command that carries several. | |
raw | string | Conditional | Request bytes as they would follow ipmitool raw: netfn, cmd, then data. See IPMI Raw Commands. | |
sol | SolObject | Conditional | Capture the host console over Serial over LAN. Needs lan. See IPMI SOL. | |
expect | Expectation or list | Yes | What the value must satisfy. A list is checked against the same value or response. | |
where | map | No | Narrows a wildcard get to records whose fields match, such as { type: threshold }. A value matches as eq; a map with one operator filters by it. See Checking every sensor or FRU. | |
exclude | []string | No | Sensor names, FRU ids or SEL record ids a wildcard get leaves out. | |
retry | {timeout, interval} | No | Read again every interval (default 2s) until every expectation passes or timeout ends. See IPMI Retry. | |
variable | string | No | Store the value read for later steps as {{ NAME }}. See IPMI Variables. | |
lan | LanObject | No | Reach the BMC over lanplus. Without it, ipmitool runs in-band on the transport target. | |
placeholders | []string | No | see below | Values programmed rejects, compared ignoring case; * matches any text. Defaults to To be filled by O.E.M., Default string, Not Specified and *-NOT-FILLED. |
IPMI Lan Options
| Attribute | Type | Required | Description |
|---|---|---|---|
host | string | Yes | BMC host name or address |
user | string | No | IPMI user |
password | string | No | IPMI password. Masked in the step log. |
cipher | integer or string | No | lanplus cipher suite, such as 17 |
IPMI Paths
| Path | Fields |
|---|---|
sdr/<sensor>/<field> | name, reading, unit, state, type, lower-non-recoverable, lower-critical, lower-non-critical, upper-non-critical, upper-critical, upper-non-recoverable, number, entity |
fru/<id>/chassis/<field> | type, part-number, serial, extra |
fru/<id>/board/<field> | mfg-date, manufacturer, product, serial, part-number, fru-id, extra |
fru/<id>/product/<field> | manufacturer, name, part-number, version, serial, asset-tag, fru-id, extra |
sel/<id>/<field> | id, time, sensor-type, sensor, event, direction, detail |
Sensor names and FRU ids are used exactly as the BMC reports them. A sensor name may contain spaces or /.
sdr reads ipmitool -c sensor, and also ipmitool sdr elist for the sensor number (0x98), the entity (10.1) and the states of discrete sensors. fru reads ipmitool fru print, and a SEL entry ipmitool sel elist. Every other path sends one IPMI command; see IPMI Commands.
For a discrete sensor, state lists the asserted states as ipmitool sdr elist names them, comma-separated: Presence detected, Power Supply AC lost. The step runs sdr elist only when it reads or filters on number, entity or the state of a discrete sensor. A sensor keeps its hex bitmap (0x0080) when elist names no state, for example for an OEM sensor type. ipmitool cuts names to 16 characters, so two sensors can share a name; they pair with the elist rows of that name in SDR order.
Values are normalized:
- Enumerations are lowercase:
on,hard-reset,sms-os,always-off. - Booleans are
trueorfalse. - Durations carry a unit:
300s,120.5s. - Timestamps are RFC 3339 in UTC. The SEL’s “never” reads as
unspecified, and time counted from BMC start aspre-init <n>s. - A threshold sensor’s
stateisipmitool’s status:ok,nc,cr,nrorna. A discrete sensor’sstateis its list of asserted states, or a hex bitmap (see above). guidis the 16 bytes of Get System GUID, which IPMI sends least significant first, as an RFC 4122 string.- A list is comma-separated, such as
ipmi,sol, ornone.
A field the BMC does not report is absent. exists and programmed also treat an empty FRU field as absent, whether ipmitool omits it or prints it blank.
IPMI Commands
These paths send the IPMI command raw and decode the reply from the IPMI 2.0 and DCMI 1.5 specifications, so they do not depend on ipmitool’s text output. <channel> takes 0 to 15, <payload> takes ipmi, sol, oem-explicit or a number, and every number in a path may be decimal or hex (channel/0x0f/protocol).
| Path | Fields | Command |
|---|---|---|
device/<field> | device-id, device-revision, provides-sdrs, available, firmware-revision, ipmi-version, supports, manufacturer-id, product-id | Get Device ID |
guid | Get System GUID | |
device-guid | Get Device GUID | |
self-test (passed, not-implemented, device-error, fatal-hardware-error), self-test-errors | Get Self Test Results | |
acpi-system (s0 to s5, s4-s5, g3, sleeping, g1-sleeping, override, legacy-on, legacy-off, unknown), acpi-device (d0 to d3, unknown) | Get ACPI Power State | |
watchdog/<field> | timer-use, running, logging, timeout-action, pre-timeout-interrupt, pre-timeout-interval, expired, initial-countdown, present-countdown | Get Watchdog Timer |
channel/<channel>/<field> | number, medium, protocol, sessions, active-sessions, vendor-id | Get Channel Info |
access-mode, alerting, privilege-limit, as in effect | Get Channel Access | |
payloads, session-payloads, oem-payloads | Get Channel Payload Support | |
cipher-suites: every suite ID, such as 3,17 | Get Channel Cipher Suites | |
channel/<channel>/auth/<field> | auth-types, logins, user-level-auth, per-message-auth, kg-set, ipmi-v15, ipmi-v20, oem-id | Get Channel Authentication Capabilities |
channel/<channel>/payload/<payload>/version | version | Get Channel Payload Version |
payload/<payload>/<field> | capacity, active instances | Get Payload Activation Status |
session/<field> | privilege of the session the step runs in | Set Session Privilege Level, without a change |
handle, slots, active, user, channel | Get Session Info | |
system-info/<field> | set-in-progress, firmware-version, system-name, primary-os-name, os-name, os-version, bmc-url, hypervisor-url | Get System Info Parameters |
user/<id>/<field> | name | Get User Name |
privilege, messaging, link-auth, callback-only, enabled, on channel 1 | Get User Access | |
users/<field> | max, enabled and fixed-names user IDs, on channel 1 | Get User Access |
chassis/<field> | power, power-overload, interlock, power-fault, power-control-fault, power-restore-policy, last-power-event, intrusion, front-panel-lockout, drive-fault, cooling-fault, identify | Get Chassis Status |
minutes-per-count, power-on-hours | Get POH Counter | |
restart-cause, restart-channel | Get System Restart Cause | |
boot/<field> | set-in-progress | Get System Boot Options, parameter 0 |
valid, persistent, type (legacy, efi), cmos-clear, lock-keyboard, device, screen-blank, lock-reset-button, lock-power-button, verbosity, progress-traps, password-bypass, lock-sleep-button, console-redirection, bios-shared-mode, bios-mux, device-instance | Get System Boot Options, parameter 5: the boot flags | |
fru/<id>/<field> | size in bytes, access (byte or word) | Get FRU Inventory Area Info |
fru/<id>/header/<field> | version, internal-offset, chassis-offset, board-offset, product-offset, multirecord-offset (bytes, 0 when the area is absent), checksum-ok | Read FRU Data, the common header |
fru/<id>/byte/<offset> | the byte at the offset | Read FRU Data |
sdr/<field> | version, records, free-bytes, last-add, last-erase, overflow, update-modes, supports | Get SDR Repository Info |
reservation | Reserve SDR Repository | |
time | Get SDR Repository Time | |
sdr-record/<id>/<field> | next, id, version, type, length; record 0 is the first | Get SDR |
device-sdr/<field> | sdrs, dynamic | Get Device SDR Info, SDR count |
sensors | Get Device SDR Info, sensor count | |
reservation | Reserve Device SDR Repository | |
sel/<field> | version, entries, free-bytes, last-add, last-erase, overflow, supports | Get SEL Info |
time | Get SEL Time | |
reservation | Reserve SEL | |
lan/<channel>/<field> | set-in-progress, ip, ip-source, mac, netmask, gateway, gateway-mac, backup-gateway, backup-gateway-mac, community, vlan (off or the ID), vlan-priority | Get LAN Configuration Parameters |
sol/<channel>/<field> | set-in-progress, enabled, force-encryption, force-authentication, privilege, accumulate-interval, send-threshold, retry-count, retry-interval, bit-rate, volatile-bit-rate, payload-channel, port | Get SOL Configuration Parameters |
dcmi/<field> | version, sel-entries | Get DCMI Capabilities Info, platform attributes |
controller-id | Get Management Controller Identifier String | |
asset-tag | Get Asset Tag | |
dcmi/power/<field> | current, minimum, maximum, average, period, active | DCMI Get Power Reading |
The step log lists every field of the reply under the raw bytes, with ✗ before the field the step read when its check failed, and with the code of a named value: privilege administrator (0x04). A reply that spans several requests, such as the cipher suites or a DCMI string, is read to its end.
A named value, a boolean and a list also have their raw value, the code. A number in a check compares with the code, written in decimal or hex, so each pair below is the same check:
When the text of a field is a number itself, such as the bit rate 115200, a number compares with the text. contains on a list looks for one item, so contains: 17 matches 3,17 but not 117.
These paths can check the completion code like raw, so a refused request reads as what it is. Without a completion check, a non-zero completion code fails the step.
SEL entries
sel/<id>/<field> reads one entry of the event log, by record id (0x1a or 26), last for the newest one, or * for every entry. sel/<field> stays the log’s own information (version, entries, time).
| Field | Example |
|---|---|
id | 0x1a |
time | 2026-10-14T09:02:41Z; pre-init, a time since BMC start (S+ 00:01:23) or a time in another zone stays as ipmitool prints it |
sensor-type | Power Supply |
sensor | PSU0_Status, or #0x98 when the BMC has no SDR for it |
event | Power Supply AC lost |
direction | asserted or deasserted |
detail | Reading 95 > Threshold 90 degrees C |
Checking every sensor or FRU
* in place of a sensor name or FRU id checks every one. where narrows the set by other fields of the same record:
The report counts passes and names each member that failed:
A wildcard that matches nothing fails the step, because it checked nothing, unless a count expectation allows zero.
A plain where value matches as eq does. A map with one operator filters by eq, ne, ge, le, range, matches or contains. name filters sdr by sensor name, and id filters fru by device id (for fru, name stays the product name field). A record without the field never matches a condition, and a regular expression is checked when the step is validated:
count checks how many records the wildcard matched, after where and exclude. It can stand alone or next to checks on each record, and a failed count names the records it found (up to ten):
distinct checks that no two matched records hold the same non-empty value and names the records that share one, for example get: sdr/*/number with expect: distinct. sum adds up the field over the matched records and compares the total; a record without a number fails the sum and is named. With a variable, the DCMI power reading checks the PSU power:
exclude leaves named sensors or FRU ids out of a wildcard, for example a sensor for a fan that is not populated on this board:
The report header names the exclusions. An excluded name the BMC does not report is listed as “excluded but not reported by the BMC”, so a stale entry is visible after a rename. SEL entries are excluded by record id in the forms get takes, 0x1a or 26.
IPMI Expectations
An expectation is one operator and its value, written as a map, or one of four bare words. The operator names match the Redfish inventory rules.
| Operator | Passes when the value |
|---|---|
eq, ne | equals or differs. Durations compare as durations (5m equals 300s), numbers as numbers (0x0f equals 15), anything else as text. |
ge, le | is at least or at most this number or duration |
range | lies within min..max, inclusive, or within a tolerance around a centre: 450±10%, 12±0.6 (+- works as ±). The report shows the bounds: range 450±10% (405..495). |
matches | matches the regular expression |
contains | contains the text; on a list, such as cipher-suites, holds the item |
within | is a timestamp no further than this duration from the runner’s clock, such as { within: 1m } for sel/time |
completion | raw, set and the IPMI Commands of get: the completion code equals this value |
count | wildcard get only: the number of matched records equals a whole number, or compares with eq, ne, ge, le or range (count: { ge: 1 }) |
sum | wildcard get only: the total of the matched records’ values compares like count does (sum: { range: 450±10% }) |
exists | bare word: the field is present and non-empty |
programmed | bare word: the field is present, non-empty and not a placeholder |
distinct | bare word, wildcard get only: no two matched records hold the same non-empty value |
refused | bare word, with lan only and the only expectation of its step: the BMC answers but refuses the session. See IPMI Refused Sessions. |
More than one operator in one expectation is an error. To check a value from both sides, use range or a list:
IPMI Set
set writes value to a path, as ipmitool raw would send it, and checks the completion code like raw. A value is a name or its number, decimal or hex, wherever the field reads as a name: value: cycle and value: 0x02 send the same request. A command that carries several fields takes them as a map.
| Path | value | Command |
|---|---|---|
chassis/power | off, on, cycle, reset, diag or soft | Chassis Control |
chassis/power-restore-policy | always-off, previous, always-on, or no-change to only read the supported policies | Set Power Restore Policy |
chassis/identify | off, on until turned off, or seconds (15s or 15) | Chassis Identify |
boot/set-in-progress | complete, in-progress or commit-write | Set System Boot Options, parameter 0 |
boot/flags | the fields of boot/<field>; valid is true unless given | Set System Boot Options, parameter 5 |
device/reset | cold or warm | Cold Reset or Warm Reset of the BMC |
watchdog | reset, off, or the fields of watchdog/<field>, with timer-use and with clear for the expiration flags to clear | Reset Watchdog Timer, Set Watchdog Timer |
session/privilege | a privilege level | Set Session Privilege Level |
user/<id>/name | up to 16 ASCII characters; "" deletes the user on OpenBMC | Set User Name |
user/<id>/password | up to 20 ASCII characters, masked in the step log | Set User Password, set |
user/<id>/password-test | the password to test: 0x00 matches, 0x80 does not | Set User Password, test |
user/<id>/enabled | true or false | Set User Password, enable or disable |
user/<id>/privilege | as get reads it; on channel 1 it also turns IPMI messaging on and link auth and callback-only off | Set User Access |
sel/time | an RFC 3339 time or seconds since 1970 | Set SEL Time |
sel/entry | sensor-type, sensor and event-type (threshold, sensor-specific or a number); optional direction, event-data (up to 3 bytes; 0x00 and the rest 0xff, unspecified), generator (0x20), evm-revision (0x04), record-type (system-event), timestamp | Add SEL Entry |
lan/<channel>/<field> | as get reads it: set-in-progress, ip, ip-source, mac, netmask, gateway, gateway-mac, backup-gateway, backup-gateway-mac, vlan (off or an ID), vlan-priority | Set LAN Configuration Parameters |
sol/<channel>/<field> | as get reads it: set-in-progress, enabled, bit-rate, volatile-bit-rate, payload-channel, port | Set SOL Configuration Parameters |
watchdog: off sends what ipmitool mc watchdog off sends: SMS/OS use, no action, its expiration flag cleared, 300 s. A SOL field that shares its parameter with others, such as privilege, is written with raw.
IPMI Raw Commands
raw sends request bytes exactly as they would follow ipmitool raw, for any request, also one that get or set names, for example with a wrong length on purpose. Expectations then check the completion code or the response data:
| Attribute | Type | Default | Description |
|---|---|---|---|
completion | integer or string | The completion code equals this value. 0x00 is success, 0xc1 is Invalid Command. | |
byte | integer | Offset of the first data byte to check. 0 is the first byte after the completion code. | |
len | integer | 1 | Number of bytes read as one little-endian value, up to 8 |
mask | integer or string | Bit mask applied before comparing |
A byte check takes eq, ne, ge, le or range.
The second step sends the command once and checks both expectations against the same response, which matters for commands such as Reserve SDR Repository that change state on every call.
When a raw command fails and no expectation checks completion, the step reports the completion code once instead of failing every byte check for the same reason.
A non-zero completion code is the BMC’s answer, not a tool failure, so the log shows it as BMC response: completion code 0xc7: Request data length invalid instead of the ipmitool error text.
IPMI SOL
sol captures the host console over Serial over LAN for duration, and can send one line. It needs lan, because ipmitool opens the SOL session over lanplus, and GNU timeout where the step runs (normally the runner):
| Attribute | Type | Required | Description |
|---|---|---|---|
duration | string | Yes | How long the capture runs at most. |
send | string | No | One line sent after wait, ended with CR as the Enter key sends it. It must not start with ~, the SOL escape character of ipmitool. |
wait | string | No | Delay before send. |
until | string | No | Text that ends the capture early once it appears (plain text, not a regular expression). |
The step first deactivates a SOL session that is still open, so a stale one does not block the capture. It removes terminal escape sequences, turns CR and CRLF into newlines, and logs the end of the console (the last 16 KiB). expect takes matches, contains and exists on the console text and names the line where it found the text; use (?m) for ^ and $ per line. retry and variable do not apply: capture longer with duration instead. Without an options timeout, the step timeout is the default plus duration; an options timeout that does not outlast duration is rejected.
IPMI Refused Sessions
expect: refused passes when the BMC answers and turns the lanplus session down: an unknown user, a wrong password, a cipher suite or a privilege level it does not accept. ipmitool runs with -v, which prints the reason, and the report names it. A BMC that does not answer at all is not a refusal and fails the step, so a switched-off BMC cannot pass a security check:
A session that opens fails the check, also when only the command is then rejected with a completion code; check that with completion.
IPMI Retry
retry repeats the read and every expectation until they all pass or timeout ends, every interval (default 2s). It applies to get and raw, and it also covers a BMC that does not answer yet, for example while it reboots:
The log shows the last attempt in full, then how the retry ended (passed on attempt 4 after 6s, or still failing after 31 attempts in 1m0s) and one line per earlier failed attempt, with repeats of the same failure merged: attempts 1 to 3 at +0s to +4s: ✗ eq on got "off". When the step needs discrete states, every attempt runs sdr elist again, so a state that changes is seen.
Without an options timeout, the step timeout is the default of 2 minutes plus the retry timeout. An options timeout shorter than the retry timeout is rejected when the step is validated.
IPMI Variables
variable: NAME stores the value a single get read, or the data bytes of a successful raw command as hex without spaces (3412ab), for later steps as {{ NAME }}:
The value is stored even when an expectation fails, because it is what the BMC reported. Nothing is stored when no value was read. A wildcard get stores the number of records it matched, after where and exclude. With retry, the value of the last attempt is stored. Stored values keep only A-Z a-z 0-9 / _ . : + -; when that drops characters (the space in degrees C), the log says so next to the stored value.
IPMI Transport
transport is optional and defaults to local.
- With
lan,ipmitoolconnects over lanplus (-I lanplus -H -U -P -C) from wherever the step runs. With the default transport, that is the contest runner, which needs network access to the BMC’s IPMI port (UDP 623). - Without
lan,ipmitoolruns in-band on the transport target. Use ansshtransport to the BMC itself; this works whether or not the BMC’s IPMI LAN channel is enabled. solalways needslan, and GNUtimeouton the host that runsipmitool.
IPMI Security
- The
lanpassword is passed toipmitoolas a command-line argument, so it is briefly visible in the process list (ps,/proc/<pid>/cmdline) of the host that runsipmitoolwhile the step runs. It is masked in the step log. This is acceptable for lab BMCs with shared credentials. - In-band checks over
sshsend no IPMI credentials at all.