Skip to content

Hyper V Discovery

Ed Mozley edited this page Oct 26, 2026 · 4 revisions

Hyper-V and Failover Cluster discovery

FreeITSM can show your Hyper-V estate - standalone hosts, Failover Clusters, their nodes and roles, and every virtual machine - in Assets β†’ Servers, beside vCenter, Proxmox and Cloud Director.

A small read-only PowerShell collector runs as a scheduled task on one of your Windows servers. It reads the hosts and clusters you name and sends what it found to FreeITSM. FreeITSM never connects to your hosts, so this works wherever FreeITSM runs, including Docker on Linux.

Built for issue #199: all three parts of the design - the estate in Assets, building the CMDB from it, and redundancy-aware impact.

⚠️ The collector has not yet been run against a real Hyper-V estate. It was written against Microsoft's documentation and tested end to end with mocked cmdlets. Run it with -TestAccess and -OutputFile before you schedule it, and please report anything that does not match what your hosts return.


No Hyper-V to try it on? System -> Demo Data -> Virtualisation imports a demo estate - a two-node cluster, a standalone host, a migration, an identity change and the CMDB built from it - and removes it again. See Demo Data.

Setting it up

1. Add a connection

Assets β†’ Settings β†’ Hyper-V β†’ Add:

Field What it means
Name What this estate is called here, e.g. Production clusters
Company Everything this connection reports belongs to this company (multi-company installs). It cannot be changed later - make a second connection for another company
Expected every (minutes) How often your scheduled task runs. A report later than this shows as Late
Overdue after a further (minutes) How much later still before it is Overdue - on this tab, on Assets β†’ Servers and on System β†’ Background jobs
Remove VMs not seen for (days) Empty (the default) keeps them, marked not seen since, until you remove them
Accept reports Untick to stop accepting reports without deleting anything

Save shows the connection's key, once. Copy it straight away: only its fingerprint is kept. The key can send this connection's reports and nothing else. FreeITSM refuses reports for this connection from any other key, even one with the same permission. New key makes a new one and stops the old one at once.

It also shows the command to schedule, with your FreeITSM address and connection number filled in.

2. Prepare the Windows management server

Any Windows Server that can reach your hosts and clusters, and FreeITSM over HTTPS:

Install-WindowsFeature Hyper-V-PowerShell, RSAT-Clustering-PowerShell
PowerShell Status
Windows PowerShell 5.1 on Windows Server 2016 or later Supported
PowerShell 7.4 or later Expected to work, not yet proven on a real estate

Copy scripts/Invoke-HyperVInventory.ps1 from FreeITSM to the server, e.g. C:\FreeITSM\.

3. Give its account read access

A group-managed service account is the natural choice. Account names and arrangements stay on your network; nothing about them is sent.

Target Grant
Each Failover Cluster Grant-ClusterAccess -Cluster <name> -User <account> -ReadOnly
Each Hyper-V host Hyper-V has no read-only role. The local Hyper-V Administrators group works, but it also allows changes the collector never makes. A narrower grant - Enable Account and Remote Enable on the root\virtualization\v2 and root\cimv2 WMI namespaces, plus Remote Management Users - may be enough. Check with -TestAccess

4. Check what it can read

.\Invoke-HyperVInventory.ps1 -Cluster CL-PROD,CL-DR -StandaloneHost HV-LAB01 -TestAccess

It tries every read against every cluster and host and prints what worked and what was refused. It sends nothing and writes nothing.

5. Look at a report before sending one

.\Invoke-HyperVInventory.ps1 -Cluster CL-PROD -OutputFile C:\Temp\hyperv.json

-Redact replaces names, addresses, MAC addresses, file paths, identifiers and error text with placeholders. The same VM gets the same placeholder every run, keyed on a secret kept in %ProgramData%\FreeITSM\redact.key. A redacted report still needs a person to read it before it is shared - no filter catches everything. The fully synthetic examples in samples/hyperv/ show what a report looks like without anyone's estate in it.

6. Schedule it

powershell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\FreeITSM\Invoke-HyperVInventory.ps1" `
  -ApiUrl "https://itsm.example.com" -ConnectionId 3 -ApiKey "fitsm_..." `
  -Cluster "CL-PROD","CL-DR" -StandaloneHost "HV-LAB01" -ReportPer Cluster

as a scheduled task, at the interval you set on the connection. For an internal FreeITSM with a self-signed certificate, add -CertificateThumbprint, as for the inventory agent.

-ReportPer Cluster sends one report per cluster and one for the standalone hosts. Use it for anything but a small estate:

  • one unreachable cluster cannot hold up the others
  • reports stay small: a single report for 8,000 VMs is about 7.5 MB, close to PHP's default upload limit of 8 MB

What you see

Assets β†’ Servers

  • Hyper-V VMs in the main table, beside the other sources, with their host, cluster, and Highly available for VMs that are clustered roles.
  • A Hyper-V reports panel: each connection's last report, how often it is expected, and On time, Late or Overdue. There is no Sync button for Hyper-V - FreeITSM waits for the collector.
  • Hosts and clusters (click the Hosts or Clusters card): each cluster with its nodes, VMs and quorum, and each host with its state, VM count, and how it is identified - alongside the other sources' hosts. Click a host to list only its VMs.

When a read fails

FreeITSM never treats a failed read as "gone":

What happened What FreeITSM does
The collector could not read a host or cluster Everything on it is kept exactly as it was, marked Not confirmed since
A VM is missing from a complete report, and its host was read Marked Not seen since that report - not deleted
A report older than the last one arrives Ignored (stale)
The same report arrives twice Recognised; nothing changes

Only you remove not-seen VMs - or the retention setting, if you set one.

Identity changes

FreeITSM recognises a VM by its Hyper-V Id, and a host by its hardware UUID:

  • A VM renamed, live-migrated or failed over stays the same record. Its moves are kept as placement history.

  • A host renamed stays the same record. A host that reports no usable UUID is identified by its name and marked Name only under Hosts and clusters.

  • A VM imported as a copy gets a new Id (Microsoft's register and restore imports keep it), and a host with a replaced motherboard gets a new UUID. When something comes back with a new identity while something with the same name stops being seen, FreeITSM asks. The connection on Assets β†’ Settings β†’ Hyper-V shows Identity changes to review:

    • Same machine keeps the old record - its history, and later its configuration item - under the new identity.
    • Different machines keeps both.

    If either one changes before you decide - the old one is seen again, say - the case closes rather than act on what is no longer true.

System β†’ Background jobs

Each connection appears as Hyper-V reports: <name>. It is healthy while reports arrive on time, overdue when they stop, and partial when the last report could not read everything. A monitor watching FreeITSM's health address sees it too.


Building the CMDB from it

Assets β†’ Settings β†’ Hyper-V β†’ CMDB on a connection turns its estate into configuration items and keeps them in step. It is off until you switch it on, and you see what it would do first.

  1. Map it onto your CMDB. Choose which of your classes a cluster, a host, a VM and a cluster role become (a kind left not mapped is skipped), and which of your relationship types join them:

    Relationship From β†’ to For impact analysis, make it
    Host to its cluster host β†’ cluster Redundant membership
    Highly available VM to its node VM β†’ node Placement with failover
    Other VM to its host VM β†’ host an ordinary dependency
    Role to its cluster role β†’ cluster an ordinary dependency

    Suggest fills the form with Cluster, Hypervisor host, Virtual machine, Cluster role and four relationship types already set up that way. It reuses yours where the names match - a relationship type only if it also points impact the same way, so a runs on of your own that works differently is left alone and runs on (discovered) is made beside it - and creates the rest - for someone allowed to change the CMDB's classes and relationship types. Nothing is mapped until you Save.

  2. Look at what it would do. Per kind: how many are already bound, how many it would create, and anything it will not decide alone:

    • A CI with the same name already exists. A name is not proof, so you choose: Bind to that CI, Create a new one, or Leave unbound.
    • Waiting: an object with an identity change not yet reviewed gets nothing until you decide.
    • A class with required properties discovery cannot fill is flagged before anything is created.
  3. Tick Keep the CMDB in step and Save. The first sync runs straight away, then after every report.

What it changes - and what it never touches

  • It creates a CI for each discovered object, in the connection's company, and binds the two. A rename, live migration, failover or a reviewed identity change keeps the same CI.
  • It keeps the CI's name in step, unless you untick CI names follow the source.
  • It manages only the relationships it made. A migration moves one runs on, and never makes a second CI. Relationships, never containment, so deleting a host's CI can never take its VMs with it.
  • It never touches owners, properties, or a relationship a person drew - the applications on a VM stay exactly as you linked them, and that is what lets impact reach them.
  • Discovered facts are shown, not copied. A bound CI has a Discovered card - source, state, host, cluster, highly available, CPUs, memory, last seen - read live, the same way the Asset card shows an asset. Someone who cannot open Assets sees only Discovered - restricted.
  • A VM that is not seen keeps its CI, and its relationships: not seen is not gone. The retention setting never removes a discovered object that has a CI.
  • If you delete the connection, its CIs stay as ordinary CIs, with their relationships. Each one's From discovery card says it is no longer bound.
  • If you delete a bound CI, it is not recreated on the next report. The object waits under the connection's CMDB panel: Create a new CI or Leave unbound.

The CI's own asset link (#201) is separate and still works: a VM's CI can be bound to the discovered VM and linked to the asset the same machine has from Intune, a spreadsheet or the inventory agent.

Impact, with discovery

On bound CIs, the four grades use what discovery knows instead of assuming. A node that is up counts as somewhere to fail over to. A node the last report could not read makes the answer unknown. A VM's possible owners narrow where it can go: a highly available VM whose only possible owner failed is affected, whatever else is in the cluster.


What it does not do

  • Change anything. It only calls Get-* cmdlets and CIM reads. No SCVMM, nothing installed on the hosts.
  • Storage. Cluster Shared Volumes and Storage Spaces Direct are not collected yet; the Servers page says so.
  • Monitoring. It is inventory, not a health check: it never opens incidents or changes a status page.
  • Several companies on one connection. One connection belongs to one company.

REST

POST /virtual-estate/{connection}/reports What the collector sends - only from the connection's own key
GET /virtual-estate/{connection} On time or not, and what the estate holds - for your own monitoring

Details: REST API - Assets.


Related pages

FreeITSM

Getting Started

Modules

Multi-tenancy (planned)

Blue sky thinking

Bugs resolved

Links

Clone this wiki locally