banshee est en développement actif : les collecteurs vont encore changer, et une version que vous publiez demandera sans doute des ajustements. Pour un usage stable, attendez la version 1.0.0.

Virtualization

banshee/virtualization-collection/virtualization/hyperv/winrm/

checkpoints

The number and the age of the oldest checkpoint of each virtual machine of a Hyper-V host, by WinRM and PowerShell.

  • virtualization
  • hyper-v
  • windows
  • winrm
  • powershell
  • checkpoint
  • snapshot

par banshee1 installation1 version

v1Dernière

Publiée le 27 octobre 2026. First version.

Keen 1.0.0 · 64 lignes
// The checkpoints of the virtual machines of a Hyper-V host, by WinRM: for each machine, how many it has and
// the age of the oldest. A checkpoint forgotten grows its differencing disk until the volume is full, and a
// backup that failed may leave its own behind.
// Runs one PowerShell script that only reads two WMI classes of Hyper-V, whose properties and values Microsoft
// documents (root\virtualization\v2): Msvm_ComputerSystem (ElementName, the name; Name, the id of the
// machine, a GUID that tells it from the host) and Msvm_VirtualSystemSettingData, one per checkpoint of a
// machine (VirtualSystemType "Microsoft:Hyper-V:Snapshot:..."; VirtualSystemIdentifier, the id of the
// machine; CreationTime, turned into days on the host, by its own clock). The recovery points that Hyper-V
// Replica keeps on a replica ("Microsoft:Hyper-V:Snapshot:Replica:...") are left to it.
// With $ErrorActionPreference set to Stop, a right missing on Hyper-V ends the script with no answer, rather
// than an empty list.
need('protocol:winrm');

per('vm', 'Virtual machines');
output('checkpoints', 'number', array('label' => 'Checkpoints', 'per' => 'vm'));
output('oldest', 'number', array('label' => 'Age of the oldest checkpoint', 'unit' => 'd', 'per' => 'vm'));

watch.above('old', 'Old checkpoint', 'oldest', array('warning' => 7, 'critical' => 30));
watch.above('many', 'Many checkpoints', 'checkpoints', array('warning' => 5, 'enabled' => false));

$read = winrm.run("$ErrorActionPreference = 'Stop'; "
    . "[Console]::OutputEncoding = New-Object System.Text.UTF8Encoding; "
    . "$now = Get-Date; "
    . "ConvertTo-Json -Compress -Depth 3 -InputObject @{"
    . "vms = @(Get-CimInstance -Namespace root\\virtualization\\v2 -ClassName Msvm_ComputerSystem"
    . " | Where-Object Name -match '^[0-9A-Fa-f]{8}-' | Select-Object ElementName, Name); "
    . "checkpoints = @(Get-CimInstance -Namespace root\\virtualization\\v2 -ClassName Msvm_VirtualSystemSettingData"
    . " | Where-Object { $_.VirtualSystemType -like 'Microsoft:Hyper-V:Snapshot:*'"
    . " -and $_.VirtualSystemType -notlike 'Microsoft:Hyper-V:Snapshot:Replica:*' }"
    . " | Select-Object VirtualSystemIdentifier, @{Name = 'Days'; Expression = {($now - $_.CreationTime).TotalDays}})}");
$answer = text.trim($read['output']);
if (list.count(text.match($answer, '^\{')) == 0) {
    fail('misconfigured', 'PowerShell did not return the checkpoints', $answer . $read['errors']);
}
$read_checkpoints = json.read($answer);

// {"checkpoints": [{"VirtualSystemIdentifier": "0B8C5A1E-...", "Days": 12.4}, ...]}: counted and the oldest
// kept, by machine.
$count = array();
$oldest = array();
foreach ($read_checkpoints['checkpoints'] as $checkpoint) {
    $id = text.lower($checkpoint['VirtualSystemIdentifier']);
    $count[$id] = list.get($count, $id, 0) + 1;
    if ($checkpoint['Days'] > list.get($oldest, $id, -1)) {
        $oldest[$id] = $checkpoint['Days'];
    }
}

// {"vms": [{"ElementName": "web01", "Name": "0B8C5A1E-..."}, ...]}: each machine, with 0 when it has no
// checkpoint. Two machines of one name each keep their own, the second carrying its id, as in
// hyperv/winrm/vms.
$seen = array();
foreach ($read_checkpoints['vms'] as $vm) {
    $name = $vm['ElementName'];
    if (list.has($seen, $name)) {
        $name = $name . ' #' . $vm['Name'];
    }
    $seen[$name] = true;
    $id = text.lower($vm['Name']);
    value('checkpoints', list.get($count, $id, 0), $name);
    if (list.has($oldest, $id)) {
        value('oldest', number.round($oldest[$id], 1), $name);
    }
}