The Powershell script discussed in this article will help you to find out the physical host name of a virtual machine using powershell. It works for both VMware based virtual machines and Hyper-V based virtual machines.
Virtualization is growing very fast and many companies switching most of their infrastructure to virtual space. Depending on budget and feature set requirements companies are switching to VMware or Hyper-V virtualization. In some cases, they place critical servers in VMware and low priority in Hyper-V. Since the virtual world is spread across multiple platforms, there is a need to identify the physical host of a given virtual machine. Though companies maintain some sort of naming convention, it is not a full-fledged solution to determine if a host is physical or virtual. This is even truer in cases where P2V is performed to migrate physical machines to virtual world where name of the computer is not changed. I too had such requirement and thought that building a script for this is very useful for everyone.
Each virtual machine stores the physical host information in registry at “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters” in PhysicalHostName value. So to get physical host name of a virtual machine, we should just query the data of aforementioned registry value. The below script helps you in that course. Before querying the registry, first it verifies if the given host is virtual or not by verifying its mode. This is done by querying model attribute of Win32_ComputerSystem WMI class. If it is a virtual machine, then the script makes a remote registry call using [Microsoft.Win32.RegistryKey] dotnet class and connects to HKLM and then queries the value of the key mentioned before.
The script is capable of taking multiple computers from command line find their physical host names.
Save the below code into a file (Get-PhysicalHostName.ps1 for example) and use as shown below.
.\get-physicalhostname.ps1 –computername computer1,computer2
[This code is working for only Hyper-V servers at the moment. I am working on how to device this information for VMware VMs as well]
[cmdletbinding()] param( [string[]]$ComputerName = $env:ComputerName ) $KeyName = "SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters" $ValueName = "PhysicalHostName" foreach($Computer in $ComputerName) { if(!(Test-Connection -ComputerName $Computer -Count 1 -quiet)) { Write-Warning "$Computer is offline" Continue } try { $CompObj = Get-WMIObject -Class Win32_ComputerSystem -ComputerName $Computer -ErrorAction Stop if($CompObj.Model -notmatch "Virtual") { throw "Not a virtual machine" } } catch { Write-Warning "$Computer : FAILED. Details : $_" Continue } try { $BaseKeyObj = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine", $computer) $KeyObj = $BaseKeyObj.OpenSubKey($KeyName) $Hostname = $KeyObj.GetValue($ValueName) } catch { Write-Warning "$Computer : Failed to get Physical host name. Details : $_" Continue } $OutputObj = New-Object PSObject -Prop ( @{ ComputerName = $Computer.ToUpper() PhysicalHostName = $Hostname }) $OutputObj }
Hope this helps…