Agent
...
Hypervisor Discovery
Hyper-V Configuration
6 min
description collects hyper v configuration information from a hyper v host powershell \#requires runasadministrator <# synopsis retrieves hyper v host configuration details using wmi/cim description queries the local hyper v host for configuration information including \ host details (name, os version) \ virtual switches (name, type, notes, bound nic for external) \ default paths (vm configuration files, virtual hard disks) \ live migration settings (enabled, networks, authentication) \ storage migration settings (max concurrent) \ replication settings (enabled, authentication, ports) \ general host settings (numa spanning, enhanced session mode) \ virtual sans (fibre channel) outputs the collected data as a single json object representing the host config notes author based on user request and ai generation date 2025 04 07 requires powershell v3+, hyper v role installed, administrator privileges running context designed to run locally on the hyper v host \#> \# define the hyper v wmi namespace $namespace = "root\virtualization\v2" $erroractionpreference = 'stop' # stop on non terminating errors within try blocks write output "attempting to retrieve hyper v host configuration from wmi namespace '$namespace' " \# initialize an object to store all host configuration details $hostconfig = \[pscustomobject]@{ hypervhost = $env\ computername osversion = $null timestamputc = (get date) touniversaltime() tostring('o') # iso 8601 format virtualswitches = @() defaultvmconfigpath = $null defaultvhdpath = $null livemigrationsettings = $null storagemigrationsettings = $null replicationsettings = $null generalsettings = $null virtualsans = @() } try { \# get basic host info try { $osinfo = get ciminstance classname win32 operatingsystem erroraction stop $hostconfig osversion = "$($osinfo caption) $($osinfo version) build $($osinfo buildnumber)" } catch { write warning "could not retrieve os version using win32 operatingsystem error $($ exception message)" \# fallback or alternative method could be added here if needed } \# get virtual switches (networks) write host "querying virtual switches " $switches = get ciminstance namespace $namespace classname msvm virtualethernetswitch erroraction stop $switchdetails = @() if ($switches) { foreach ($switch in $switches) { $switchname = $switch elementname $switchnotes = $switch notes $switchtype = "unknown" # default type $boundadaptername = $null \# get associated settings data for the switch type $switchsettingdata = get cimassociatedinstance inputobject $switch resultclassname msvm virtualethernetswitchsettingdata erroraction silentlycontinue | select object first 1 if ($switchsettingdata) { \# switch type logic can be complex, often inferred from associations or properties \# check for associated external port > indicates external switch $externalport = get cimassociatedinstance inputobject $switch resultclassname msvm externalethernetport erroraction silentlycontinue | select object first 1 if ($externalport) { $switchtype = "external" \# the elementname of the externalethernetport usually contains the physical nic description $boundadaptername = $externalport elementname } else { \# if not external, check if it's internal or private \# internal switches have a host nic associated via msvm internalethernetport $internalport = get cimassociatedinstance inputobject $switch resultclassname msvm internalethernetport erroraction silentlycontinue | select object first 1 if ($internalport) { $switchtype = "internal" $boundadaptername = $internalport elementname # name of the virtual host nic } else { $switchtype = "private" # if not external or internal, assume private } } \# could add more details from $switchsettingdata if needed (iov, bandwidth settings etc ) \# $iovenabled = $switchsettingdata iovenabled \# $bandwidthreservationmode = $switchsettingdata bandwidthreservationmode } $switchdetails += \[pscustomobject]@{ name = $switchname type = $switchtype notes = $switchnotes boundadaptername = $boundadaptername # name of physical nic (external) or host vnic (internal) \# add other properties like iovenabled, bandwidth settings here if desired } } } else { write warning "no virtual switches found " } $hostconfig virtualswitches = $switchdetails \# get default paths write host "querying default paths " try { \# these paths are typically stored in the management service settings $mgmtsvc = get ciminstance namespace $namespace classname msvm virtualsystemmanagementservice erroraction stop | select object first 1 if ($mgmtsvc) { $hostconfig defaultvmconfigpath = $mgmtsvc defaultexternaldataroot # path for vm config files (xml/vmcx) $hostconfig defaultvhdpath = $mgmtsvc defaultvirtualharddiskpath # path for vhd files } else { write warning "could not retrieve msvm virtualsystemmanagementservice instance " } } catch { write warning "failed to query default paths from msvm virtualsystemmanagementservice error $($ exception message)" } \# get live migration settings write host "querying live migration settings " try { $lmsettings = get ciminstance namespace $namespace classname msvm virtualsystemmigrationservicesettingdata erroraction stop | select object first 1 if ($lmsettings) { $migrationnetworks = @() \# get associated network settings (allowed subnets) $networksettings = get cimassociatedinstance inputobject $lmsettings resultclassname msvm migrationnetworksettingdata erroraction silentlycontinue if ($networksettings) { $migrationnetworks = $networksettings subnetnumber # array of allowed subnets } $hostconfig livemigrationsettings = \[pscustomobject]@{ enabled = $lmsettings enablevirtualsystemmigration authenticationtype = $lmsettings virtualsystemmigrationauthenticationtype # credssp, kerberos useanynetwork = $lmsettings useanymigrationnetwork allowednetworks = $migrationnetworks # array of subnet strings like "192 168 1 0/24" performanceoption = $lmsettings migrationperformanceoption # e g , tcp/ip, compression, smb simultaneousmigrations = $lmsettings maximumactivevirtualsystemmigrations # max concurrent vm migrations } \# add storage migration setting (often part of the same object) $hostconfig storagemigrationsettings = \[pscustomobject]@{ simultaneousmigrations = $lmsettings maximumactivestoragemigrations } } else { write warning "could not retrieve msvm virtualsystemmigrationservicesettingdata instance " $hostconfig livemigrationsettings = @{ status = "not found" } $hostconfig storagemigrationsettings = @{ status = "not found" } } } catch { write warning "failed to query live migration settings error $($ exception message)" $hostconfig livemigrationsettings = @{ status = "query failed"; error = $ exception message } $hostconfig storagemigrationsettings = @{ status = "query failed"; error = $ exception message } } \# get replication settings write host "querying replication settings " try { $replsettings = get ciminstance namespace $namespace classname msvm replicationservicesettingdata erroraction stop | select object first 1 if ($replsettings) { $hostconfig replicationsettings = \[pscustomobject]@{ enabled = $replsettings recoveryserverenabled # true if host is enabled as a replica server authenticationtype = $replsettings authenticationtype # kerberos, certificate httpport = if ($replsettings enablehttplistener) { $replsettings httpport } else { $null } httpsport = if ($replsettings enablekerberoslistener or $replsettings enablecertificatelistener) { $replsettings httpsport } else { $null } certificatethumbprint = if ($replsettings authenticationtype eq 'certificate') {$replsettings certificatethumbprint } else {$null} monitoringinterval = $replsettings monitoringinterval # seconds monitoringstarttime = $replsettings monitoringstarttime # time string allowedprimaryservers = $replsettings allowedprimaryserver # policy entries (may require further parsing if complex) } } else { write warning "could not retrieve msvm replicationservicesettingdata instance replication may not be configured " $hostconfig replicationsettings = @{ status = "not configured or not found" } } } catch { write warning "failed to query replication settings error $($ exception message)" $hostconfig replicationsettings = @{ status = "query failed"; error = $ exception message } } \# get general host settings write host "querying general host settings " try { $generalsettings = get ciminstance namespace $namespace classname msvm virtualsystemmanagementservicesettingdata erroraction stop | select object first 1 if ($generalsettings) { $hostconfig generalsettings = \[pscustomobject]@{ numaspanningenabled = $generalsettings numaspanningenabled enhancedsessionmodeenabled = $generalsettings enhancedsessionmodeenabled \# add other settings from here if needed, e g , default stop action defaultautomaticstopaction = $generalsettings automaticstopaction } } else { write warning "could not retrieve msvm virtualsystemmanagementservicesettingdata instance " $hostconfig generalsettings = @{ status = "not found" } } } catch { write warning "failed to query general host settings error $($ exception message)" $hostconfig generalsettings = @{ status = "query failed"; error = $ exception message } } \# get virtual sans (fibre channel) write host "querying virtual sans " try { $virtualsans = get ciminstance namespace $namespace classname msvm virtualsan erroraction stop if ($virtualsans) { $sandetails = @() foreach ($san in $virtualsans) { $sandetails += \[pscustomobject]@{ name = $san elementname wwnn = $san nodeworldwidename wwpn = $san portworldwidename status = $san status healthstate = $san healthstate operationalstatus = $san operationalstatus } } $hostconfig virtualsans = $sandetails } else { write host "no virtual sans found " \# keep $hostconfig virtualsans as empty array } } catch { \# silentlycontinue might be better if vsans aren't expected write warning "failed to query virtual sans feature might not be installed or configured error $($ exception message)" } write host "successfully gathered hyper v host configuration " } catch { \# catch errors during the overall process write error "a critical error occurred while gathering hyper v host configuration error at line $($ invocationinfo scriptlinenumber) $($ exception message)" \# output whatever was collected so far, possibly with an error flag $hostconfig errorstate = "incomplete due to error $($ exception message)" } \# output generation \# convert the final host configuration object to json format \# depth 5 should be sufficient $jsonoutput = $hostconfig | convertto json depth 5 compress \# output the json string write output $jsonoutput \# optional save json to a file \# $jsonfilepath = "c \programdata\hypervinventory\\$(get date format 'yyyymmddhhmmss') hypervhostconfig json" \# # ensure directory exists \# $jsondirpath = split path $jsonfilepath parent \# if ( not (test path $jsondirpath)) { \# new item itemtype directory path $jsondirpath force | out null \# } \# try { \# $jsonoutput | out file filepath $jsonfilepath encoding utf8 erroraction stop \# write host "host configuration json saved to $jsonfilepath" \# } catch { \# write error "failed to save host configuration json to '$jsonfilepath' error $($ exception message)" \# } write host "script finished " database tables table hostconfiguration stores the main configuration settings for each inventoried hyper v host column name data type constraints description hypervhost text primary key not null name of the hyper v host osversion text operating system version string timestamputc datetime not null utc timestamp when this inventory record was created/updated defaultvmconfigpath text default path for storing vm configuration files defaultvhdpath text default path for storing virtual hard disk files lm enabled integer live migration enabled? (0=false, 1=true) lm authenticationtype text live migration authentication type (e g , "credssp", "kerberos") lm useanynetwork integer use any available network for live migration? (0=false, 1=true) lm performanceoption text live migration performance option (e g , "tcpip", "compression", "smb") lm simultaneousmigrations integer max concurrent live migrations allowed sm simultaneousmigrations integer max concurrent storage migrations allowed repl enabled integer hyper v replica enabled on this server? (0=false, 1=true) repl authenticationtype text replica authentication type ("kerberos", "certificate") repl httpport integer replica http listener port (if enabled) repl httpsport integer replica https listener port (if enabled) repl certificatethumbprint text certificate thumbprint used for replica auth (if applicable) repl monitoringinterval integer replica monitoring interval in seconds repl monitoringstarttime text replica monitoring start time (e g , "hh\ mm\ ss") repl allowedprimaryservers text policy for allowed primary servers (might be complex, store as text/json) gen numaspanningenabled integer numa spanning enabled? (0=false, 1=true) gen enhancedsessionmodeenabled integer enhanced session mode enabled? (0=false, 1=true) gen defaultautomaticstopaction text default vm action on host shutdown (e g , "save", "turnoff", "shutdown") errorstate text records any errors encountered during data collection for this host table host virtualswitches stores details about each virtual switch configured on a hyper v host column name data type constraints description hypervhost text not null, foreign key(hypervhost) references hostconfiguration(hypervhost) links back to the specific host in hostconfiguration name text not null name of the virtual switch type text type of switch ("external", "internal", "private", "unknown") notes text notes/description associated with the virtual switch boundadaptername text name of the bound physical nic (for external) or host vnic (for internal) constraint primary key (hypervhost, name) composite primary key ensures switch name uniqueness per host table host virtualsans stores details about each fibre channel virtual san configured on a hyper v host column name data type constraints description hypervhost text not null, foreign key(hypervhost) references hostconfiguration(hypervhost) links back to the specific host in hostconfiguration name text not null name of the virtual san wwnn text world wide node name of the virtual fibre channel hba wwpn text world wide port name of the virtual fibre channel hba status text reported status string from wmi healthstate integer numerical health state code from wmi operationalstatus integer numerical operational status code array from wmi (might store as text) constraint primary key (hypervhost, name) composite primary key ensures san name uniqueness per host table host livemigrationallowednetworks stores the specific network subnets allowed for live migration on a hyper v host column name data type constraints description hypervhost text not null, foreign key(hypervhost) references hostconfiguration(hypervhost) links back to the specific host in hostconfiguration subnetnumber text not null allowed subnet for live migration (e g , "192 168 1 0/24") constraint primary key (hypervhost, subnetnumber) composite primary key ensures subnet uniqueness per host's lm config