【PowerShell】「仮想マシン」か「物理マシン」かを見分ける 2 ~ (2012.2.15 15:36 追記)


※ 2012.2.15 VMWare Workstation 6.5 – 7.x に関して追記しました(最後尾)
※ 2012.2.15 VMWare ESXi 4.1 に関して追記しました(最後尾)
※ 2012.2.14 VMWare Workstation 8 に関して追記しました(最後尾)

前回の投稿は以下の通りです。

【PowerShell】「仮想マシン」か「物理マシン」かを見分ける 1

前回の投稿では、Windows PowerShell を使用して「仮想マシン」か「物理マシン」を見分ける方法についてご紹介しました。方法といっても、たった1行のスクリプトですが。

では、さらに一歩踏み込んで、どんなタイプの仮想マシンなのかを判断することはできないでしょうか?

そのヒントとなるスクリプトが Microsoft Deployment Toolkit  2012(MDT 2012) Beta で提供されていました。

ためしに、上記サイトから MDT 2012 Beta をダウンロードしてインストールしてみてください。以下のスクリプトが見つかるはずです。

C:\Program Files\Microsoft Deployment Toolkit\Templates\Distribution\Scripts\ZTIGather.wsf

※以前のMDTにも含まれていますので無理にダウンロードする必要はありません

以下にスクリプト内から GetVirtualizationInfo という Function を抜粋したものを掲載します。簡単にコメントも追記しておきました。ここに、さまざまな仮想化プラットフォームの識別方法が vbs で書かれています。重要なのはスクリプト内で赤く太字にした部分です。WMI の Win32_ComputerSystem Win32_BIOS を使用していることがわかります。つまり、Win32_ComputerSystem の Model プロパティで大まかに仮想化ベンダーを判定し、さらに Win32_BIOS の Version プロパティを使用してマイクロソフトの製品名を特定しています。

※ZTIGather.wsf 抜粋(スクリプト言語は VBS です)

'//---------------------------------------------------------------------------
'//  Function:    GetVirtualizationInfo()
'//  Purpose:    Get virtualization details
'//---------------------------------------------------------------------------
Function GetVirtualizationInfo

    Dim oInstance, oInstances
    Dim sVersionString
    Dim bIsVM, sVMPlatform
    Dim sVMHost, sVMName

    oLogging.CreateEntry "Getting virtualization info", LogTypeInfo

    ' Set variables based on the capabilities of the hardware

    oEnvironment.Item("IsHypervisorRunning") = oUtility.ConvertBooleanToString(oUtility.BDDUtility.IsHypervisorRunning)
    oEnvironment.Item("SupportsVT") = oUtility.ConvertBooleanToString(oUtility.BDDUtility.SupportsVT)
    oEnvironment.Item("SupportsNX") = oUtility.ConvertBooleanToString(oUtility.BDDUtility.SupportsNX)
    oEnvironment.Item("Supports64Bit") = oUtility.ConvertBooleanToString(oUtility.BDDUtility.Supports64Bit)
    If oUtility.BDDUtility.SupportsVT and oUtility.BDDUtility.SupportsNX and oUtility.BDDUtility.Supports64Bit then
        oEnvironment.Item("SupportsHyperVRole") = "True"
    Else
        oEnvironment.Item("SupportsHyperVRole") = "False"
    End if

    ' Determine what virtual machine environment this might be.  Get the BIOS version information

    Set oEnvironment = objWMI.ExecQuery("Select * from Win32_ComputerSystem")

    Set oInstances = objWMI.ExecQuery("Select * from Win32_BIOS")
    For each oInstance in oInstances
        sVersionString = oInstance.Version
    Next

    ' Check the BIOS version information against known values

    bIsVM = false
    sVMPlatform = ""

   If oEnvironment.Item("Model") = "Virtual Machine" then

        ' Microsoft virtualization technology detected, assign defaults

        sVMPlatform = "Hyper-V"
        bIsVM = true

        ' Try to determine more specific values

        Select Case sVersionString
        Case "VRTUAL - 1000831"
            bIsVM = true
            sVMPlatform = "Hyper-V Beta or RC0"
        Case "VRTUAL - 5000805", "BIOS Date: 05/05/08 20:35:56  Ver: 08.00.02"
            bIsVM = true
            sVMPlatform = "Hyper-V"
        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

        ' Try to get the VM host from the integration components

        sVMHost = ""
        On Error Resume Next
        sVMHost = oShell.RegRead("HKEY_LOCAL_MACHINE\Software\Microsoft\Virtual Machine\Guest\Parameters\PhysicalHostNameFullyQualified")
        If Err then
            oLogging.CreateEntry "The VM physical host name was not found.", LogTypeVerbose
        Else
            oEnvironment.Item("VMHost") = sVMHost
        End if
        On Error Goto 0

        ' Try to get the VM namefrom the integration components

        sVMName = ""
        On Error Resume Next
        sVMName = oShell.RegRead("HKEY_LOCAL_MACHINE\Software\Microsoft\Virtual Machine\Guest\Parameters\VirtualMachineName")
        If Err then
            oLogging.CreateEntry "The VM name was not found.", LogTypeVerbose
        Else
            oEnvironment.Item("VMName") = sVMName
        End if
        On Error Goto 0

    ElseIf oEnvironment.Item("Model") = "VMware Virtual Platform" then

        ' VMware detected

        sVMPlatform = "VMware"
        bIsVM = true

    ElseIf oEnvironment.Item("Model")  = "VirtualBox" then

        ' VirtualBox detected

        bIsVM = true
        sVMPlatform = "VirtualBox"

    ElseIf oEnvironment.Item("Make")  = "Xen" then

        ' Xen server detected

        bIsVM = true
        sVMPlatform = "Xen"

    Else
        oLogging.CreateEntry "This computer does not appear to be a virtual machine (BIOS is '" & sVersionString & "').", LogTypeInfo
    End if

    ' Set the appropriate variables

    oEnvironment.Item("IsVM") = oUtility.ConvertBooleanToString(bIsVM)
    If sVMPlatform <> "" then
        oEnvironment.Item("VMPlatform") = sVMPlatform
    End if

    oLogging.CreateEntry "Finished getting virtualization info", LogTypeInfo

End function

上記のスクリプトをごく簡単に PowerShell に書き換えたものが以下の通りです。

MS 製品と XEN は概ね確認しましたが、VMWare と VirtualBOX は確認しておりません。

どなたか、間違いがあればご指摘いただけるとうれしいです。

$oEnvironment = Get-WmiObject Win32_ComputerSystem
$oInstance = Get-WmiObject Win32_BIOS

if ($oEnvironment.Model -eq "Virtual Machine") {
    $vmPlatform = "Microsoft"
    switch($oInstance.Version) {
    "VRTUAL - 3000919" {$vmPlatform =  $vmPlatform + " Windows Server 2008 R2 Hyper-V"}
    "VRTUAL - 5000920" {$vmPlatform =  $vmPlatform + " Windows Server 2008 Hyper-V"}
    "A M I  - 2000622" {$vmPlatform =  $vmPlatform + " VS2005R2SP1 or VPC2007"}
    "A M I  - 9000520" {$vmPlatform =  $vmPlatform + " VS2005R2"}
    "A M I  - 9000816" {$vmPlatform =  $vmPlatform + " Windows Virtual PC"}
    "A M I  - 6000901" {$vmPlatform =  $vmPlatform + " Windows Virtual PC"}
    "A M I  - 8000314" {$vmPlatform =  $vmPlatform + " VS2005 or VPC2004"}   
    default {$vmPlatform =  $vmPlatform + "?????"}
    }
} elseif ($oEnvironment.Model -eq "VMware Virtual Platform") {
    $vmPlatform = "VMWare"
} elseif ($oEnvironment.Model -eq "VirtualBox") {
    $vmPlatform = "Oracle VM VirtualBox"
} elseif ($oEnvironment.Model -eq "HVM domU") {
    $vmPlatform = "Xen"
} else {
    $vmPlatform = "unknown platform"
}

$vmPlatform
 

Xen については AWS の環境を借りて確認しました(クラウドって超便利!)。

image

単にベンダー識別するだけならば、Manufacture を見ればよさげですね。

参考までに、以下もご覧ください。

[Windows 7] XP Mode か実機か Virtual PC か Hyper-V か見分ける方法とは? - 管理者は見た!~AD と ILM 一家の秘密~ - Site Home - TechNet Blogs

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

2012.2.14 23:36 追記

@YoshihiroOkabe さんが VMWare Workstation 8 で検証してくださいました。

その結果、Model = Virtual Machine (← MS製品と同じ)であることが判明。全製品同様というわけでは無いと思われますが、少なくとも Manufacture も判断材料に入れないと正確には識別できないことがわかりました。

image

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

2012.2.15 0:16 追記

@GUCHI2010 さんが VMWare ESXi4.1 で検証してくださいました。

こちらは、Model = "VMware Virtual Platform" になるとの情報をいただきました。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

2012.2.15 15:43 追記

えぬなんとかわーるど の 山市良さんからも情報をいただきました

※詳しくはコメント欄をご覧ください

(ご参考)山市良のえぬなんとかわーるど: 仮想マシンのホスト環境をゲストからどこまで識別できるのか?

Comments (3)

  1. 匿名 より:

    山市さんありがとうございます!

    なるほど、ハイパーバイザーではなく、「仮想マシンのバージョン」という考え方があるのですね。

    ※VMWareに疎くてすいません

    Workstation 6.5 – 7.x "VMware Virtual Platform"

    Workstation 8 "Virtual Machine"

    ってかんじですね。

  2. yamaichi ryo より:

    VMWare Player 4.01 の場合、Model=VMware Virtual Platform です。ちなみに、"Workstation 6.5-7.x 仮想マシン"バージョンの仮想マシン (VMware の場合、これが関係するかも)。

    PS C:UsersAdministrator> Get-WMIObject Win32_ComputerSystem

    Domain              : contoso.local

    Manufacturer        : VMware, Inc.

    Model               : VMware Virtual Platform

    Name                : WIN-0D0KIVHDTGI

    PrimaryOwnerName    : Windows ユーザー

    TotalPhysicalMemory : 1626857472

    PS C:UsersAdministrator> Get-WmiObject Win32_BIOS

    SMBIOSBIOSVersion : 6.00

    Manufacturer      : Phoenix Technologies LTD

    Name              : PhoenixBIOS 4.0 Release 6.0

    SerialNumber      : VMware-56 4d ff 3c 4e 6d aa e4-3d f4 7a 29 d3 1e 0b fa

    Version           : INTEL  – 6040000

    以前、Hyper-V のバージョンの識別にチャレンジしたことあります。yamanxworld.blogspot.com/…/blog-post.html

  3. yamaichi ryo より:

    ちょっと違います。VMware Player だと仮想マシンのバージョンは選択できないのですが (直接構成ファイルをいじればなんとかなるかもしれません)、VMware Workstation や VMware ESXi だと、仮想マシン作成時にバージョンを指定できます。VMware ESXi の場合、バージョン4(VMware ESX Server 3.0以降、3.5以前、VMware Server 1.0 以降と互換)とバージョン 7(VMware ESX Server 4.0以降、VMware Server 2.0 互換)の2種類から選択できます。VMware Workstation は手元にないのですが、バージョンを選択できて、ESX 用の仮想マシンを作れたりするんだと思います。

Skip to main content