Windows
banshee/windows-collection/windows/snmp/
volumes
The space of each fixed volume of a Windows, and when it will be full, by SNMP
by banshee1 installation2 versions
v2Latest
Published on October 28, 2026. One naming convention across collections; documentation completed.
// The space of each fixed volume of a Windows, by SNMP, from hrStorageTable (HOST-RESOURCES-MIB):
// the rows of the type hrStorageFixedDisk only, so that network, removable and optical drives
// are not among them. An expected volume that disappears shows through the watch "Volume missing".
// Neither the IOPS nor the latency of the disks can be read this way: the Windows SNMP agent does not serve them.
// hrStorageSize holds on 31 bits: a volume of more than 2^31 allocation units (8 TiB in units
// of 4 KiB) is miscounted by the agent itself.
need('protocol:snmp');
per('volume', 'Volumes');
output('used-percent', 'number', array('label' => 'Used space', 'unit' => '%', 'per' => 'volume'));
output('used', 'number', array('label' => 'Used space', 'unit' => 'GiB', 'per' => 'volume'));
output('free', 'number', array('label' => 'Free space', 'unit' => 'GiB', 'per' => 'volume'));
output('size', 'number', array('label' => 'Size', 'unit' => 'GiB', 'per' => 'volume'));
watch.above('used', 'Used space', 'used-percent', array('warning' => 80, 'critical' => 90));
watch.above('full-soon', 'Full within a week', 'used-percent', array('warning' => 99, 'ahead' => '7 d'));
watch.below('free', 'Little free space', 'free', array('critical' => 5, 'enabled' => false));
watch.missing('missing', 'Volume missing', 'used-percent', array('enabled' => false));
// hrStorageTable, indexed by hrStorageIndex: hrStorageType (an OID), hrStorageDescr ("C:\ Label:System
// Serial Number 1a2b3c4d"), hrStorageAllocationUnits (in bytes), hrStorageSize and hrStorageUsed (in units).
$storage = snmp.table(array(
'type' => '1.3.6.1.2.1.25.2.3.1.2',
'descr' => '1.3.6.1.2.1.25.2.3.1.3',
'unit' => '1.3.6.1.2.1.25.2.3.1.4',
'size' => '1.3.6.1.2.1.25.2.3.1.5',
'used' => '1.3.6.1.2.1.25.2.3.1.6',
));
// The types read, each once, to say what the agent served when no volume is returned.
$rows = 0;
$seen_types = array();
$types = array();
$volumes = 0;
foreach ($storage as $row) {
$rows = $rows + 1;
$type = list.get($row, 'type', '');
if (!list.has($seen_types, $type)) {
$seen_types[$type] = true;
$types = list.add($types, $type);
}
// hrStorageFixedDisk is 1.3.6.1.2.1.25.2.1.4; the pattern accepts the OID written with or without a leading dot.
// A volume of zero size (not mounted, not formatted) has no space to judge.
if (!text.like($type, '*1.3.6.1.2.1.25.2.1.4') || list.get($row, 'size', 0) <= 0) {
continue;
}
$volumes = $volumes + 1;
// The name of the volume is its letter or its mount point, before " Label:".
$parts = text.split($row['descr'], ' Label:');
$name = text.trim($parts[0]);
$total = $row['size'] * $row['unit'] / 1073741824;
$used = $row['used'] * $row['unit'] / 1073741824;
value('size', number.round($total, 1), $name);
value('used', number.round($used, 1), $name);
value('free', number.round($total - $used, 1), $name);
value('used-percent', number.round(100 * $used / $total, 1), $name);
}
// A Windows always has at least its system volume: returning none would be a green light on nothing.
// The empty table, a type written in a form the pattern does not recognise, or no fixed disk of
// non-zero size therefore stop the collector, saying what it read.
if ($volumes == 0) {
fail('misconfigured', 'No fixed disk read in hrStorageTable',
$rows . ' row(s) read; types: ' . text.join($types, ', '));
}