Repository navigation
Hyper V 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-TestAccessand-OutputFilebefore 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.
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.
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\.
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
|
.\Invoke-HyperVInventory.ps1 -Cluster CL-PROD,CL-DR -StandaloneHost HV-LAB01 -TestAccessIt tries every read against every cluster and host and prints what worked and what was refused. It sends nothing and writes nothing.
.\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.
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 Clusteras 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
- 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.
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.
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.
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.
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.
-
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.
-
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.
-
Tick Keep the CMDB in step and Save. The first sync runs straight away, then after every report.
- 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.
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.
-
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.
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.
FreeITSM β an open-source IT Service Management platform Β· github.com/edmozley/freeitsm Β· MIT licence
- Installation
- β° Scheduled tasks (cron jobs)
-
Architecture
- β³ π§Ή Root folder tidy (URL routing)
- β³ π Database Integrity (FKs & constraints)
- β³ π οΈ Database Verification β Developer Guide
- β³ π§© Service Layer (UI + API share code)
- β³ πͺ€ Code traps (the TRAP: comments)
- β³ π Commenting for the Engineering wiki
- β³ π οΈ Engineering wiki scanner - Developer Guide
- β³ π Service-Layer progress
- π€ Contributing (read before a pull request)
- π§ͺ Developer tests
- AI Providers
- Internationalisation (i18n)
- Timezones & Time Handling
- π Date & Time Formats
- π± Currencies
- π§ The sidebar (optional module rail)
- π§© Preference templates
- π Display order (modules, Watchtower cards) β Developer Guide
- Theming & Dark Mode
- ποΈ Recent β getting back to what you were doing
- β¨οΈ Command palette (βK)
- π Searching inside tickets
- π Attached documents
-
MobileβFriendly
- β³ π« Mobile: Tickets
- β³ π» Mobile: Assets
- β³ π Mobile: Calendar
- β³ π Mobile: Knowledge
- β³ π¦ Mobile: Service Status
- β³ πΌ Mobile: Watchtower
- β³ π§© Mobile: Problem Management
- β³ π Mobile: Change Management
- β³ πΏ Mobile: Software
- β³ β Mobile: Tasks
- β³ π Mobile: Forms
- β³ π Mobile: Contracts
- β³ π Mobile: Domains
- β³ π Mobile: People
- β³ π Mobile: Projects
- β³ ποΈ Mobile: Files
- β³ π Mobile: LMS
- β³ πΊοΈ Mobile: CMDB
- β³ πΊοΈ Mobile: Network Mapper
- β³ π§ Mobile: Process Mapper
- β³ βοΈ Mobile: Workflow
- β³ π₯οΈ Mobile: System
- β³ π Mobile: Reporting
- β³ π Mobile: System Wiki
- β³ π Mobile: Self-Service Portal
- β³ π§° Mobile: Techniques & Tricks
-
Security
- Layer 1 β which modules you can enter
- β³ π§© Module Access Control
- β³ π οΈ Module Access β Developer Guide
- β³ π Switching modules off
- β³ π οΈ Module availability β Developer Guide
- β³ π Module availability β design (#217)
- Layer 2 β what you can administer
- β³ π Roles & Permissions
- β³ π οΈ Roles β Developer Guide
- β³ π€ Why capabilities are constants
- Layer 3 β the System module
- β³ π Admin Access Control
- Hardening
- β³ π Security review response 2026-08
- β³ π‘οΈ Security hardening 2026-08
- β³ π οΈ Security hardening 2026-08 β Developer Guide
- β³ π‘οΈ Round three β plain English
- β³ π οΈ Round three β Developer Guide
- β³ π‘οΈ CSRF protection (S4) β Developer Guide
- Single Sign-On (SSO)
- ποΈ LDAP & Active Directory
- π CardDAV contact sync
- Browser Extension
- API Reference
-
π REST API β how it works
- β³ π Proposal: custom fields, inventory import and change evidence (#194)
- β³ π οΈ Custom fields, evidence + inventory - review (#195-#197)
- β³ π οΈ Long forms in a task's Work view - review (#198)
- β³ π« REST API: Tickets
- β³ π» REST API: Assets
- β³ π΄ REST API: Problems
- β³ π REST API: Changes
- β³ π REST API: Knowledge
- β³ β REST API: Tasks
- β³ ποΈ REST API: CMDB
- β³ π REST API: Contracts
- β³ ποΈ REST API: Calendar
- β³ πΏ REST API: Software
- β³ π REST API: Domains
- β³ π¦ REST API: Service Status
- β³ βοΈ REST API: Morning Checks
- β³ π REST API: Forms
- β³ βοΈ REST API: Workflow
- β³ π·οΈ REST API: Cost centres
- β³ π§βπΌ REST API: Analysts
- β³ πΊοΈ REST API: Network Mapper
- β³ π§ Using the API docs page
- β³ π OpenAPI specification
- β³ β OpenAPI: kept correct
- β³ π οΈ Maintaining the catalogue
- Watchtower
-
Tickets
- β³ π οΈ Inbox.js map β Developer Guide
- β³ π οΈ Tickets settings β Developer Guide
- β³ ποΈ The ticket workspace
- β³ π The ticket table
- β³ π Rota copy and paste β Developer Deep Dive
- β³ β Checklists & SOPs
- β³ βοΈ Mandatory fields
- β³ π§Ύ Custom ticket fields
- β³ π·οΈ Ticket categories
- β³ π₯ Assigning tickets to a team, and escalation
- β³ π’ One board across every company
- β³ Mailbox Authentication
- β³ π€ Email send log
- β³ π Attachment size limits and large emails
- β³ Basic IMAP mailboxes
- β³ Email rendering & images
- β³ SLA Management
- β³ WhatsApp channel
-
β³
βοΈ Telegram channel - β³ β CSAT company scope and filters β Developer Guide
- β³ π₯ Microsoft Teams channel
- β³ π¨οΈ Mattermost channel
- β³ π¬ Web chat channel
- β³ π£ Slack channel
- β³ π Linking tickets
- β³ β Record previews
- β³ π Ticket notes: internal or shared
- β³ ποΈ Canned responses
- β³ βοΈ Limiting replies to particular senders
- β³ π¨ Telling the analyst a ticket is theirs
- β³ βοΈ Email signatures
- β³ π The public web address
- β³ π’ Ticket numbering
- β³ π Raising a ticket for someone else
- β³ π Merging tickets
- β³ π Confidential tickets
- β³ π₯ Portal managers
- β³ π Who has seen a ticket
- β³ π Reading long tickets
- β³ β Splitting tickets
- β³ β Selecting several tickets
- β³ ποΈ The folder pane
- β³ π½ Just my tickets, or no closed ones
- β³ π οΈ Snoozing tickets β Developer Guide
- β³ π₯ Collision detection
- β³ β±οΈ Time tracking
- β³ π Case reports - a ticket and its work as one PDF
- β³ π Scheduled work in your own calendar
- Problem Management
- Tasks
- π Projects
-
Assets
- β³ π’ Moving an asset between companies
- β³ π Shared asset locations
- β³ π§βπΌ Assigning assets to analysts
- β³ π Warranty and lease alerts
- β³ π Leases
- β³ π Saved table views
- β³ π¨οΈ Recording anything, and importing it
- β³ π§© Asset type layouts
- β³ π Inventory freshness
- β³ π Linked configuration item
- β³ π Connected assets
- β³ π Asset review
- β³ π·οΈ QR asset labels
- β³ π Who holds what, and handover documents
- β³ π₯οΈ The inventory agent (PowerShell)
- β³ ποΈ Proxmox VE servers
- β³ βοΈ VMware Cloud Director servers
- β³ πͺ Hyper-V and Failover Clusters
- β³ π Linking equipment to tickets
- β³ βοΈ Follow-up tasks on a ticket
- Knowledge
- Change Management
- Calendar
- Morning Checks
- Reporting
- Software
-
Forms
- β³ π¨ The form designer β Developer Guide
- β³ π Layout & the grid β Developer Guide
- β³ ποΈ Collections β grouping submissions
- β³ π Submissions as PDFs
- β³ β‘ What happens next β a form's own actions
- β³ π οΈ Sections & conditional logic β Developer Guide
- β³ π οΈ Lookup fields β Developer Guide
- β³ π‘οΈ Catalogue request approvals
- People
- Domains
- ποΈ Files
- Contracts
- Service Status
- π Notifications
- π¨ War Room
- Self-Service Portal
- LMS
- Process Mapper
- CMDB
- Network Mapper
- Workflows
- Issue trackers (Jira, Azure DevOps)
- π‘ Zabbix (monitoring)
- π¬ Microsoft Teams alerts
- π 3CX (phone system)
- System
-
Overview
- β³ π Progress tracker
- β³ Concepts & vocabulary
- β³ Email routing & mailboxes
- β³ Settings: global vs per-company
- β³ Users & self-service
- β³ Staff cross-company access
- β³ π’ One board across every company
- β³ Worked examples
- β³ Pitfalls & gotchas
- β³ Scope: what it's for
- β³ π οΈ Developer Guide (make a module multi-company)
- β³ ποΈ Case study: CMDB (a linked graph)
- β³ π§ͺ Test harness (prove it's isolated)
- What this is
-
π Bugs resolved
- β³ π» #222 The Assets page never loaded in 4.3.0
- β³ βοΈ #214 A "contains" condition did not match capitals
- β³ βοΈ #216 A workflow email from a chosen mailbox always failed
- β³ π³ The Docker image was missing PHP extensions
- β³ π A failed DNS lookup read as a missing record
- β³ π A link could change data
- β³ π Access outlived its removal
- β³ π Knowledge articles could run scripts
- β³ π Knowledge writes ignored permissions
- β³ π Company boundaries (Oct 2026)
- β³ π Smaller gaps (Oct 2026)
- β³ π Escaped text could leave its attribute
- β³ π Task descriptions were not cleaned
- β³ π Task documents ignored company scope
- β³ π Repeating tasks ignored company scope
- β³ π¬ #183 Mailbox checks overlapped
- β³ π #188 Transfer lock shown off when unknown
- β³ β #184 Subtask names and Overdue
- β³ π§© #186 Teams: the buttons did nothing
- β³ π Text in a change could run script
- β³ π AI settings changed without the AI permission
- β³ πͺ #178 Deleting an analyst failed
- β³ π« A team with no departments showed 0 tickets
- β³ π Projects: adding a phase did nothing on Save
- β³ π Leavers could still sign in
- β³ πΌοΈ Logo and courses broke on Apache with PHP-FPM
- β³ π’ Chat tickets ignored your ticket numbering
- β³ π Dates shown as a dash, or in server time
- β³ π Assets β Users showed people from other companies
- β³ π Restricted analysts could read other modules' data
- β³ πΌοΈ Replies with a picture in the thread failed to send
- β³ π Reply attachments never reached the customer
- β³ π οΈ Outbound email attachments β Developer Guide
- β³ π A global SSO provider was missing from the portal
- β³ π Behind a proxy, the SSO redirect said http
- β³ βοΈ The portal tagline moved when you saved it
- β³ π¨ The portal settings screen forgot what you saved
- β³ π‘οΈ The approvals inbox said "Error" and nothing else
- β³ π A table's answers were missing from the PDF
- β³ β A single-select column let you tick every option
- β³ π The portal ignored a form's field widths
- β³ π The tasks board stopped taking clicks
- β³ ποΈ #121 The index list is out of date after upgrading
- β³ π #133 The calendar subscription was empty
- β³ π #131 Tasks always reopened on the board
- β³ π₯ #129 Every page returned HTTP 500 after upgrading
- β³ π³ #127 A PHP warning above the System page
- β³ π #126 Notes stamped with the server's clock
- β³ π Storing every date in UTC
- β³ πͺ The portal was down for everyone signed in
- β³ βοΈ #120 Workflow notes could never be written
- β³ βοΈ #123 Three errors when running Database Verification
- β³ π #122 The description box was a stub in the corner
- β³ π£ Demo data deleted real accounts
- β³ π #117 Sign-in redirected to the wrong address
- β³ π¨ #108 The priority dot was invisible
- β³ β±οΈ #116 Time logged from the right-click menu
- β³ π #114 API keys refused by our own guard
- β³ ποΈ #110 Assigning a task told nobody
- β³ πͺ #107 Signed out while still working
- β³ π #103 "Share with Requester" reached nobody
- β³ π #102 Search found nothing for hyphens
- β³ πͺ #101 Source code editor opened behind
- β³ βοΈ #88 Subtasks could not be ticked off
- β³ π» #84 Asset deep link selected nothing
- β³ π« #79 A new ticket arrived with no status
- β³ π§ #79 A ticket from email did not say so
- β³ π #78 Bell opened to nothing
- β³ π¬ #77 Mail only collected from Inbox
- β³ π #74 The default password could not be changed
- β³ π¦ #70 Renaming an impact level
- β³ π€ #67 App-only mailboxes could not send
- β³ π #45 Verify only ever worked for Microsoft
- β³ π #45 IMAP reported as not authenticated
- β³ βοΈ An email template stopped escaping itself
- β³ π The portal dashboard showed the wrong time
- β³ π’ The folder said 99 and the list showed 96