Sometimes you need to identify if something is running inside a Hyper-V virtual machine** before you take action. You can use this method: Determining If Hypervisor Is Installed, or Reporting the Identity of a Guest Operating System.
On a VM running on Hyper-V (and Virtual PC) , the Model property on the Win32_ComputerSystem class will return “Virtual Machine” and the “Manufacturer” will return “Microsoft Corporation”.
This sample VBScript uses the same logic found in the Microsoft Deployment Toolkit to show if a deployment is running in a VM.
If IsVM Then WScript.Quit 1 Else WScript.Quit 0 End If Function IsVM ' Check the WMI information against known values bIsVM = false sVMPlatform = "" sMake = GetWmiPropertyValue("root\cimv2", "Win32_ComputerSystem", "Manufacturer") sModel = GetWmiPropertyValue("root\cimv2", "Win32_ComputerSystem", "Model") sBIOSVersion = GetWmiPropertyValue("root\cimv2", "Win32_BIOS", "Version") WScript.Echo "Manufacturer=" & sMake WScript.Echo "Model=" & sModel WScript.Echo "BIOSVersion=" & sBIOSVersion If sModel = "Virtual Machine" then ' Microsoft virtualization technology detected, assign defaults sVMPlatform = "Hyper-V" bIsVM = true ' Try to determine more specific values Select Case sBIOSVersion Case "VRTUAL - 1000831" bIsVM = true sVMPlatform = "Hyper-V 2008 Beta or RC0" Case "VRTUAL - 5000805", "BIOS Date: 05/05/08 20:35:56 Ver: 08.00.02" bIsVM = true sVMPlatform = "Hyper-V 2008 RTM" Case "VRTUAL - 3000919" bIsVM = true sVMPlatform = "Hyper-V 2008 R2" Case "A M I - 2000622" bIsVM = true sVMPlatform = "VS2005R2SP1 or VPC2007" Case "A M I - 9000520" bIsVM = true sVMPlatform = "VS2005R2" Case "A M I - 9000816", "A M I - 6000901" bIsVM = true sVMPlatform = "Windows Virtual PC" Case "A M I - 8000314" bIsVM = true sVMPlatform = "VS2005 or VPC2004" End Select ElseIf sModel = "VMware Virtual Platform" then ' VMware detected sVMPlatform = "VMware" bIsVM = true ElseIf sModel = "VirtualBox" then ' VirtualBox detected bIsVM = true sVMPlatform = "VirtualBox" Else ' This computer does not appear to be a virtual machine. End if ' Set the return value If bIsVM Then WScript.Echo "IsVirtualMachine=True" WScript.Echo "VirtualMachinePlatform=" & sVMPlatform Else WScript.Echo "IsVirtualMachine=False" End If IsVM = bIsVM End Function Function GetWmiPropertyValue(strNameSpace, strClassName, strPropertyName) On Error Resume Next strPropertyValue = "" set oWmiClass = getobject("winmgmts:" & strNameSpace).get(strClassName,&h20000) 'amended set oWmiProperties = oWmiClass.Properties_ Set objWMIService = GetObject("winmgmts:\\" & "." & "\" & strNameSpace) Set colItems = objWMIService.ExecQuery("Select * from " & strClassName,,48) For Each objItem in colItems For Each objProperty in oWmiProperties sLine = "" 'WScript.Echo "- " & objProperty.name & ": " & strPropertyName If objProperty.Name = strPropertyName Then If objProperty.IsArray = True Then sLine = "str" & objProperty.Name & " = Join(objItem." & objProperty.Name & ", " & Chr(34) & "," & Chr(34) & ")" & vbCrLf sLine = sLine & "strPropertyValue = str" & objProperty.Name 'ElseIf objProperty.CIMTYPE = 101 Then ' bHasDates = True ' sLine = "strPropertyValue = WMIDateStringToDate(objItem." & objProperty.Name & ")" Else sLine = "strPropertyValue = objItem." & objProperty.Name End If 'WScript.Echo sLine Execute sLine End If Next Next GetWmiPropertyValue = strPropertyValue End Function
If IsVM Then WScript.Quit 1 Else WScript.Quit 0 End If
Function IsVM
' Check the WMI information against known values
bIsVM = false sVMPlatform = ""
sMake = GetWmiPropertyValue("root\cimv2", "Win32_ComputerSystem", "Manufacturer") sModel = GetWmiPropertyValue("root\cimv2", "Win32_ComputerSystem", "Model") sBIOSVersion = GetWmiPropertyValue("root\cimv2", "Win32_BIOS", "Version")
WScript.Echo "Manufacturer=" & sMake WScript.Echo "Model=" & sModel WScript.Echo "BIOSVersion=" & sBIOSVersion
If sModel = "Virtual Machine" then
' Microsoft virtualization technology detected, assign defaults
sVMPlatform = "Hyper-V" bIsVM = true
' Try to determine more specific values
Select Case sBIOSVersion Case "VRTUAL - 1000831" bIsVM = true sVMPlatform = "Hyper-V 2008 Beta or RC0" Case "VRTUAL - 5000805", "BIOS Date: 05/05/08 20:35:56 Ver: 08.00.02" bIsVM = true sVMPlatform = "Hyper-V 2008 RTM" Case "VRTUAL - 3000919" bIsVM = true sVMPlatform = "Hyper-V 2008 R2" Case "A M I - 2000622" bIsVM = true sVMPlatform = "VS2005R2SP1 or VPC2007" Case "A M I - 9000520" bIsVM = true sVMPlatform = "VS2005R2" Case "A M I - 9000816", "A M I - 6000901" bIsVM = true sVMPlatform = "Windows Virtual PC" Case "A M I - 8000314" bIsVM = true sVMPlatform = "VS2005 or VPC2004" End Select
ElseIf sModel = "VMware Virtual Platform" then
' VMware detected
sVMPlatform = "VMware" bIsVM = true
ElseIf sModel = "VirtualBox" then
' VirtualBox detected
bIsVM = true sVMPlatform = "VirtualBox"
Else ' This computer does not appear to be a virtual machine. End if
' Set the return value
If bIsVM Then WScript.Echo "IsVirtualMachine=True" WScript.Echo "VirtualMachinePlatform=" & sVMPlatform Else WScript.Echo "IsVirtualMachine=False" End If
IsVM = bIsVM
End Function
Function GetWmiPropertyValue(strNameSpace, strClassName, strPropertyName)
On Error Resume Next
strPropertyValue = "" set oWmiClass = getobject("winmgmts:" & strNameSpace).get(strClassName,&h20000) 'amended set oWmiProperties = oWmiClass.Properties_
Set objWMIService = GetObject("winmgmts:\\" & "." & "\" & strNameSpace) Set colItems = objWMIService.ExecQuery("Select * from " & strClassName,,48)
For Each objItem in colItems For Each objProperty in oWmiProperties sLine = "" 'WScript.Echo "- " & objProperty.name & ": " & strPropertyName
If objProperty.Name = strPropertyName Then If objProperty.IsArray = True Then sLine = "str" & objProperty.Name & " = Join(objItem." & objProperty.Name & ", " & Chr(34) & "," & Chr(34) & ")" & vbCrLf sLine = sLine & "strPropertyValue = str" & objProperty.Name 'ElseIf objProperty.CIMTYPE = 101 Then ' bHasDates = True ' sLine = "strPropertyValue = WMIDateStringToDate(objItem." & objProperty.Name & ")" Else sLine = "strPropertyValue = objItem." & objProperty.Name End If
'WScript.Echo sLine Execute sLine End If
Next Next
GetWmiPropertyValue = strPropertyValue
John Kelbley’s book Windows Server 2008 Hyper-V : Insiders Guide to Microsoft's Hypervisor, shares how you can use the root\CIM2 namespace and access the Baseboard class (full of interesting BIOS information) to get a description of the "physical" system. This class often includes information about the motherboard and chassis - manufacture, model, serial number, other. You can run the following VBS to get this info.
On Error Resume Next Const wbemFlagReturnImmediately = &h10 Const wbemFlagForwardOnly = &h20 arrComputers = Array(".") For Each strComputer In arrComputers WScript.Echo WScript.Echo "==========================================" WScript.Echo "Computer: " & strComputer WScript.Echo "==========================================" Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2") Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_BaseBoard", "WQL", _ wbemFlagReturnImmediately + wbemFlagForwardOnly) For Each objItem In colItems WScript.Echo "Caption: " & objItem.Caption strConfigOptions = Join(objItem.ConfigOptions, ",") WScript.Echo "ConfigOptions: " & strConfigOptions WScript.Echo " CreationClassName: " & objItem.CreationClassName WScript.Echo " Description: " & objItem.Description WScript.Echo " HostingBoard: " & objItem.HostingBoard WScript.Echo " InstallDate: " & WMIDateStringToDate(objItem.InstallDate) WScript.Echo " Manufacturer: " & objItem.Manufacturer WScript.Echo " Model: " & objItem.Model WScript.Echo " Name: " & objItem.Name WScript.Echo "OtherIdentifyingInfo: " & objItem.OtherIdentifyingInfo WScript.Echo " PartNumber: " & objItem.PartNumber WScript.Echo " Product: " & objItem.Product WScript.Echo " SerialNumber: " & objItem.SerialNumber WScript.Echo " SKU: " & objItem.SKU WScript.Echo " Status: " & objItem.Status WScript.Echo " Tag: " & objItem.Tag WScript.Echo " Version: " & objItem.Version WScript.Echo Next Next Function WMIDateStringToDate(dtmDate) WScript.Echo dtm: WMIDateStringToDate = CDate(Mid(dtmDate, 5, 2) & "/" & _ Mid(dtmDate, 7, 2) & "/" & Left(dtmDate, 4) _ & " " & Mid (dtmDate, 9, 2) & ":" & Mid(dtmDate, 11, 2) & ":" & Mid(dtmDate,13, 2)) End Function
Const wbemFlagReturnImmediately = &h10 Const wbemFlagForwardOnly = &h20
arrComputers = Array(".") For Each strComputer In arrComputers WScript.Echo WScript.Echo "==========================================" WScript.Echo "Computer: " & strComputer WScript.Echo "=========================================="
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2") Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_BaseBoard", "WQL", _ wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each objItem In colItems WScript.Echo "Caption: " & objItem.Caption strConfigOptions = Join(objItem.ConfigOptions, ",") WScript.Echo "ConfigOptions: " & strConfigOptions WScript.Echo " CreationClassName: " & objItem.CreationClassName WScript.Echo " Description: " & objItem.Description WScript.Echo " HostingBoard: " & objItem.HostingBoard WScript.Echo " InstallDate: " & WMIDateStringToDate(objItem.InstallDate) WScript.Echo " Manufacturer: " & objItem.Manufacturer WScript.Echo " Model: " & objItem.Model WScript.Echo " Name: " & objItem.Name WScript.Echo "OtherIdentifyingInfo: " & objItem.OtherIdentifyingInfo WScript.Echo " PartNumber: " & objItem.PartNumber WScript.Echo " Product: " & objItem.Product WScript.Echo " SerialNumber: " & objItem.SerialNumber WScript.Echo " SKU: " & objItem.SKU WScript.Echo " Status: " & objItem.Status WScript.Echo " Tag: " & objItem.Tag WScript.Echo " Version: " & objItem.Version WScript.Echo Next Next
Function WMIDateStringToDate(dtmDate) WScript.Echo dtm: WMIDateStringToDate = CDate(Mid(dtmDate, 5, 2) & "/" & _ Mid(dtmDate, 7, 2) & "/" & Left(dtmDate, 4) _ & " " & Mid (dtmDate, 9, 2) & ":" & Mid(dtmDate, 11, 2) & ":" & Mid(dtmDate,13, 2)) End Function
Here is a screen capture of the script results for a physical system running Windows Server 2008.
NOTE the motherboard was manufactured by Intel (model DG45ID).
Running the same script in a virtual machine returns similar information, except on the virtual machine, the "motherboard" is shows as made by Microsoft (Microsoft does not make motherboards!) and is of a virtual type.
The version number shown reflects the version of Hyper-V (Server 2008 RTM), and the Serial Number matches that found in the VM configuration file (XML file on the physical host).
The Perl script version for this is:
use strict; use Win32::OLE('in'); use constant wbemFlagReturnImmediately => 0x10; use constant wbemFlagForwardOnly => 0x20; my @computers = ("."); foreach my $computer (@computers) { print "\n"; print "==========================================\n"; print "Computer: $computer\n"; print "==========================================\n"; my $objWMIService = Win32::OLE->GetObject("winmgmts:\\\\$computer\\root\\CIMV2") or die "WMI connection failed.\n"; my $colItems = $objWMIService->ExecQuery("SELECT * FROM Win32_BaseBoard", "WQL", wbemFlagReturnImmediately | wbemFlagForwardOnly); foreach my $objItem (in $colItems) { print " Caption: $objItem->{Caption}\n"; print " ConfigOptions: " . join(",", (in $objItem->{ConfigOptions})) . "\n"; print " CreationClassName: $objItem->{CreationClassName}\n"; print " Description: $objItem->{Description}\n"; print " HostingBoard: $objItem->{HostingBoard}\n"; print " InstallDate: $objItem->{InstallDate}\n"; print " Manufacturer: $objItem->{Manufacturer}\n"; print " Model: $objItem->{Model}\n"; print " Name: $objItem->{Name}\n"; print "OtherIdentifyingInfo: $objItem->{OtherIdentifyingInfo}\n"; print " Product: $objItem->{Product}\n"; print " SerialNumber: $objItem->{SerialNumber}\n"; print " SKU: $objItem->{SKU}\n"; print " Status: $objItem->{Status}\n"; print " Tag: $objItem->{Tag}\n"; print " Version: $objItem->{Version}\n"; print "\n"; } }sub WMIDateStringToDate(strDate) { return "blah"; }
use strict; use Win32::OLE('in');
use constant wbemFlagReturnImmediately => 0x10; use constant wbemFlagForwardOnly => 0x20;
my @computers = ("."); foreach my $computer (@computers) { print "\n"; print "==========================================\n"; print "Computer: $computer\n"; print "==========================================\n";
my $objWMIService = Win32::OLE->GetObject("winmgmts:\\\\$computer\\root\\CIMV2") or die "WMI connection failed.\n"; my $colItems = $objWMIService->ExecQuery("SELECT * FROM Win32_BaseBoard", "WQL", wbemFlagReturnImmediately | wbemFlagForwardOnly);
foreach my $objItem (in $colItems) { print " Caption: $objItem->{Caption}\n"; print " ConfigOptions: " . join(",", (in $objItem->{ConfigOptions})) . "\n"; print " CreationClassName: $objItem->{CreationClassName}\n"; print " Description: $objItem->{Description}\n"; print " HostingBoard: $objItem->{HostingBoard}\n"; print " InstallDate: $objItem->{InstallDate}\n"; print " Manufacturer: $objItem->{Manufacturer}\n"; print " Model: $objItem->{Model}\n"; print " Name: $objItem->{Name}\n"; print "OtherIdentifyingInfo: $objItem->{OtherIdentifyingInfo}\n"; print " Product: $objItem->{Product}\n"; print " SerialNumber: $objItem->{SerialNumber}\n"; print " SKU: $objItem->{SKU}\n"; print " Status: $objItem->{Status}\n"; print " Tag: $objItem->{Tag}\n"; print " Version: $objItem->{Version}\n"; print "\n"; } }sub WMIDateStringToDate(strDate) { return "blah"; }
On the Windows command line you can access the same information (in Windows XP or newer) by typing the following:
wmic baseboard get manufacturer, product, Serialnumber, version
** For information on VMWare Virtual Machines see the resources below. For information on the (no longer supported) Microsoft Java Virtual Machine that you might need to detect in some versions of Internet Explorer see: http://www.microsoft.com/About/Legal/EN/US/Interoperability/Java/Default.aspx http://support.microsoft.com/gp/lifean12http://support.microsoft.com/kb/309620 For more information on how to use Hyper-V PowerShell cmdlets see: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/index.mspx New and improved PowerShell Library for Hyper-V.
For 35 sample Hyper-V PS1 scripts in a zipfile, go to: Hyper-V%20PowerShell%20Example%20Scripts.zip-download See also the Windows Dev Center Forum topic here for additional resources, including:
tonysoper_MSFT edited Revision 7. Comment: added disambiguation links for Java VM
tonysoper_MSFT edited Revision 6. Comment: + forum topic link