TechReport

技術者情報

ソリューション

2013年11月13日(水)公開

第136回

DefineSystemメソッドによるVMの世代の設定方法と、メモリの設定方法

Windows Server 2012 R2のHyper-Vから新たに追加されたDefineSystemメソッドによるVMの世代の設定方法と、メモリの設定方法

GMOインターネット株式会社 システム本部 樋口 勝一が担当するGMO最新ネット業界レポート-ソリューション編。

今回はWindows Server 2012 R2のHyper-Vから新たに追加されたDefineSystemメソッドによるVMの世代の設定方法と、メモリの設定方法をご紹介します。

記事INDEX

Windows Server 2012 R2のvirtualization名前空間

すでにWindow Server 2012 R2 の情報が出てきていますが、R2ではこれまで利用してきたroot\virtualizationという名前空間が完全に、root\virtualization\v2に置き換わることとなりました。


 > root\virtualization


 > root\virtualization\v2


Windows Server 2012、Windows Server 2012 R2 それぞれのサーバー内でWMI Explorerで見てみると、確かにR2の方は名前空間がvirtualizationの中に一つしかありません。



Windows Server 2012 のvirtualization名前空間

Windows Server 2012 R2のvirtualization名前空間

これはかなり大きな変更となります。Hyper-VのプロビジョニングをWMIで行ってきた場合、コードのほぼすべてを書き換える必要があるということです。メソッド名だけでなく、新しい機能に対応したクラスの追加や、新しいメソッドの使い方など、大幅に変更されています。ほとんどサンプルのないWMIを使ったHyper-Vのプロビジョニングですので、このGMO業界レポートで、より積極的にサンプルコードを紹介する必要が出てきました。ということで、引き続きお付き合いください。

まずは、追加情報となります。前回紹介した、VMの骨組みを作成するMsvm_VirtualSystemManagementServiceクラスの「DefineSystem」メソッドですが、Windows Server 2012 R2の登場にあわせて、重要な追加オプションが設定できるようになったのでご紹介します。

Windows Server 2012 R2のHyper-Vでは仮想マシンの世代を選択することができるようになりました。

第1世代はこれまでのHyper-V上でのVMと同様のものとなります。第2世代はレガシーBIOSや古いデバイス接続など、実マシンとの互換性を保つために備わっていた機能をすべて省き、仮想マシンとしてパフォーマンスを最大限発揮できる構成となっています。

これにより更なる高速化が実現されることとなりました。WMIでこの世代を設定するには「DefineSystem」メソッドで、「VirtualSystemSubType」プロパティーを設定する必要があります。

 
   1:  Imports System.Management
   2:   
   3:  Module GMOReport
   4:   
   5:      Sub Main()
   6:          Dim strUser As String = ""
   7:          Dim strPass As String = ""
   8:          Dim objManagementScope As ManagementScope = ConnectManagementScope("win2012.local", strUser, strPass)
   9:          Call DefineVM(objManagementScope, "VM01", "D:\Hyper-V\VM01", 2)
  10:      End Sub
  11:   
  12:      Function ConnectManagementScope(ByVal strServer As String, ByVal strAccount As String, ByVal strPassword As String) As ManagementScope
  13:          Dim objConnectionOptions As New ConnectionOptions()
  14:          objConnectionOptions.Impersonation = ImpersonationLevel.Impersonate
  15:          objConnectionOptions.EnablePrivileges = True
  16:          objConnectionOptions.Username = strAccount
  17:          objConnectionOptions.Password = strPassword
  18:          Dim objManagementScope As New ManagementScope("\\" + strServer + "\root\virtualization\v2", objConnectionOptions)
  19:          objManagementScope.Connect()
  20:          Return (objManagementScope)
  21:      End Function
  22:   
  23:      Function DefineVM(ByVal objManagementScope As ManagementScope, ByVal strVMName As String, ByVal strFolderPath As String, intGeneration As Integer) As Boolean
  24:          Dim objVirtualSystemSettingData As New ManagementClass(objManagementScope, New ManagementPath("Msvm_VirtualSystemSettingData"), Nothing)
  25:          Dim objVirtualSystemSettingDataInstance As ManagementObject = objVirtualSystemSettingData.CreateInstance
  26:          objVirtualSystemSettingDataInstance("ElementName") = strVMName
  27:          objVirtualSystemSettingDataInstance("ConfigurationDataRoot") = strFolderPath
  28:          objVirtualSystemSettingDataInstance("VirtualSystemSubType") = "Microsoft:Hyper-V:SubType:" & intGeneration
  29:          objVirtualSystemSettingDataInstance("VirtualNumaEnabled") = False
  30:          Dim strSystemsettingData As String = objVirtualSystemSettingDataInstance.GetText(TextFormat.CimDtd20)
  31:   
  32:          For Each objVirtualSystemManagementService As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_VirtualSystemManagementService")).Get
  33:              Dim objParams As ManagementBaseObject = objVirtualSystemManagementService.GetMethodParameters("DefineSystem")
  34:              objParams("SystemSettings") = strSystemsettingData
  35:              objParams("ResourceSettings") = Nothing
  36:              objParams("ReferenceConfiguration") = Nothing
  37:              Dim objManagementBaseObject As ManagementBaseObject = objVirtualSystemManagementService.InvokeMethod("DefineSystem", objParams, Nothing)
  38:              Return JobComplete(objManagementBaseObject, objManagementScope)
  39:          Next
  40:      End Function
  41:   
  42:      Function JobComplete(ByVal objManagementBaseObject As ManagementBaseObject, ByVal objManagementScope As ManagementScope) As Boolean
  43:          'JobState New = 2  Starting = 3  Running = 4  Suspended = 5  ShuttingDown = 6  Completed = 7  Terminated = 8  Killed = 9  Exception = 10  Service = 11    
  44:          If objManagementBaseObject("ReturnValue") <> 0 Then
  45:              Dim strJobPath As String = objManagementBaseObject("Job")
  46:              Dim objJob As New ManagementObject(objManagementScope, New ManagementPath(strJobPath), Nothing)
  47:              objJob.Get()
  48:              Do While objJob("JobState") = 3 Or objJob("JobState") = 4
  49:                  System.Threading.Thread.Sleep(1000)
  50:                  objJob.Get()
  51:              Loop
  52:              If objJob("JobState") <> 7 Then
  53:                  Console.WriteLine("ErrorCode=" & objJob("ErrorCode") & " JobState=" & objJob("JobState"))
  54:                  Return False
  55:              Else
  56:                  Return True
  57:              End If
  58:          Else
  59:              Return True
  60:          End If
  61:      End Function
  62:   
  63:  End Module


12行目:
引数として、引数intGenerationを追加しています。1の場合第1世代、2の場合第2世代となります。

28行目:
第1世代の場合、「VirtualSystemSubType」プロパティーには「Microsoft:Hyper-V:SubType:1」、第2世代の場合は「Microsoft:Hyper-V:SubType:2」という文字列を指定します。

29行目:
後ほどメモリの設定方法の章にて解説します。


DefineSystemメソッド実行直後のVM

第1世代

第2世代(IDE、フロッピーディスク、シリアルポートなど余計なデバイスが省略されている)

ついでに、作成したVMを削除する方法も合わせて紹介します。VMを削除するにはMsvm_VirtualSystemManagementServiceクラスの「DestroySystem」メソッドを利用します。

 
   1:  Imports System.Management
   2:   
   3:  Module GMOReport
   4:   
   5:      Sub Main()
   6:          Dim strUser As String = ""
   7:          Dim strPass As String = ""
   8:          Dim objManagementScope As ManagementScope = ConnectManagementScope("win2012.local", strUser, strPass)
   9:          Call DeleteVM(objManagementScope, "VM01")
  10:      End Sub
  11:   
  12:      Function ConnectManagementScope(ByVal strServer As String, ByVal strAccount As String, ByVal strPassword As String) As ManagementScope
  13:          Dim objConnectionOptions As New ConnectionOptions()
  14:          objConnectionOptions.Impersonation = ImpersonationLevel.Impersonate
  15:          objConnectionOptions.EnablePrivileges = True
  16:          objConnectionOptions.Username = strAccount
  17:          objConnectionOptions.Password = strPassword
  18:          Dim objManagementScope As New ManagementScope("\\" + strServer + "\root\virtualization\v2", objConnectionOptions)
  19:          objManagementScope.Connect()
  20:          Return (objManagementScope)
  21:      End Function
  22:   
  23:      Function DeleteVM(ByVal objManagementScope As ManagementScope, ByVal strVMName As String) As Boolean
  24:          Dim objComputerSystem As ManagementObject = Nothing
  25:          For Each objManagementObject As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_ComputerSystem WHERE ElementName = '" & strVMName & "'")).Get
  26:              objComputerSystem = objManagementObject
  27:          Next
  28:   
  29:          For Each objVirtualSystemManagementService As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_VirtualSystemManagementService")).Get
  30:              Dim objParams As ManagementBaseObject = objVirtualSystemManagementService.GetMethodParameters("DestroySystem")
  31:              objParams("AffectedSystem") = objComputerSystem.Path.Path
  32:              Dim objManagementBaseObject As ManagementBaseObject = objVirtualSystemManagementService.InvokeMethod("DestroySystem", objParams, Nothing)
  33:              Return JobComplete(objManagementBaseObject, objManagementScope)
  34:          Next
  35:      End Function
  36:   
  37:      Function JobComplete(ByVal objManagementBaseObject As ManagementBaseObject, ByVal objManagementScope As ManagementScope) As Boolean
  38:          'JobState New = 2  Starting = 3  Running = 4  Suspended = 5  ShuttingDown = 6  Completed = 7  Terminated = 8  Killed = 9  Exception = 10  Service = 11    
  39:          If objManagementBaseObject("ReturnValue") <> 0 Then
  40:              Dim strJobPath As String = objManagementBaseObject("Job")
  41:              Dim objJob As New ManagementObject(objManagementScope, New ManagementPath(strJobPath), Nothing)
  42:              objJob.Get()
  43:              Do While objJob("JobState") = 3 Or objJob("JobState") = 4
  44:                  System.Threading.Thread.Sleep(1000)
  45:                  objJob.Get()
  46:              Loop
  47:              If objJob("JobState") <> 7 Then
  48:                  Console.WriteLine("ErrorCode=" & objJob("ErrorCode") & " JobState=" & objJob("JobState"))
  49:                  Return False
  50:              Else
  51:                  Return True
  52:              End If
  53:          Else
  54:              Return True
  55:          End If
  56:      End Function
  57:   
  58:  End Module


29-34行目:
「DestroySystem」メソッドのパラメーター「AffectedSystem」に削除するVMの情報を設定して実行します。


削除する場合は非常にシンプルな方法となっています。

メモリの設定方法

次に紹介するのはメモリの設定方法です。


 >以前までのroot\virtualization名前空間の場合はこちら


Hyper-VはWindows Server 2012から「Non-Uniform Memory Access(NUMA)」という機能を使えるようになりました。NUMAは簡単に言えば、マルチプロセッサを利用する場合に効率よくメモリを使用することで、パフォーマンスをアップする技術です。このNUMAを利用する場合は、Hyper-Vではメモリ設定のオプションである「ダイナミックメモリ(動的メモリ)」を同時に利用することができない仕様となっています。

以前のroot\virtualization名前空間DefineVirtualSystemメソッドでVMを作成した場合は、初期設定としてNUMAは無効になっていましたが、root\virtualization\v2名前空間DefineSystemメソッドで作成したVMは、初期設定としてNUMAが有効に設定されています。したがって、メモリ設定時にダイナミックメモリを利用する場合は、事前にNUMAを無効に変更する必要があります。

前述のDefineSystemのサンプルコード内の29行目では、DefineSystemメソッド実行時にNUMAを無効にするプロパティー「VirtualNumaEnabled」をFalseにすることで、設定可能です。また、これとは別に、NUMAだけの設定をあとから変更することも可能です。この場合は「Msvm_VirtualSystemManagementService」クラスの「ModifySystemSettings」メソッドで、設定を変更することとなります。

 
   1:  Imports System.Management
   2:   
   3:  Module GMOReport
   4:   
   5:      Sub Main()
   6:          Dim strUser As String = ""
   7:          Dim strPass As String = ""
   8:          Dim objManagementScope As ManagementScope = ConnectManagementScope("win2012.local", strUser, strPass)
   9:          Call SetNumaNode(objManagementScope, "VM01", False)
  10:      End Sub
  11:   
  12:      Function ConnectManagementScope(ByVal strServer As String, ByVal strAccount As String, ByVal strPassword As String) As ManagementScope
  13:          Dim objConnectionOptions As New ConnectionOptions()
  14:          objConnectionOptions.Impersonation = ImpersonationLevel.Impersonate
  15:          objConnectionOptions.EnablePrivileges = True
  16:          objConnectionOptions.Username = strAccount
  17:          objConnectionOptions.Password = strPassword
  18:          Dim objManagementScope As New ManagementScope("\\" + strServer + "\root\virtualization\v2", objConnectionOptions)
  19:          objManagementScope.Connect()
  20:          Return (objManagementScope)
  21:      End Function
  22:   
  23:      Function SetNumaNode(ByVal objManagementScope As ManagementScope, ByVal strVMName As String, blnEnabled As Boolean) As Boolean
  24:          Dim objComputerSystem As ManagementObject = Nothing
  25:          For Each objManagementObject As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_ComputerSystem WHERE ElementName = '" & strVMName & "'")).Get
  26:              objComputerSystem = objManagementObject
  27:          Next
  28:   
  29:          Dim objVirtualSystemsettingData As ManagementObject = Nothing
  30:          For Each objManagementObject As ManagementObject In objComputerSystem.GetRelated("Msvm_VirtualSystemSettingData")
  31:              objVirtualSystemsettingData = objManagementObject
  32:              objVirtualSystemsettingData("VirtualNumaEnabled") = blnEnabled
  33:          Next
  34:   
  35:          For Each objVirtualSystemManagementService As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_VirtualSystemManagementService")).Get
  36:              Dim objParams As ManagementBaseObject = objVirtualSystemManagementService.GetMethodParameters("ModifySystemSettings")
  37:              objParams("SystemSettings") = objVirtualSystemsettingData.GetText(TextFormat.CimDtd20)
  38:              Dim objManagementBaseObject As ManagementBaseObject = objVirtualSystemManagementService.InvokeMethod("ModifySystemSettings", objParams, Nothing)
  39:              Return JobComplete(objManagementBaseObject, objManagementScope)
  40:          Next
  41:      End Function
  42:   
  43:      Function JobComplete(ByVal objManagementBaseObject As ManagementBaseObject, ByVal objManagementScope As ManagementScope) As Boolean
  44:          'JobState New = 2  Starting = 3  Running = 4  Suspended = 5  ShuttingDown = 6  Completed = 7  Terminated = 8  Killed = 9  Exception = 10  Service = 11    
  45:          If objManagementBaseObject("ReturnValue") <> 0 Then
  46:              Dim strJobPath As String = objManagementBaseObject("Job")
  47:              Dim objJob As New ManagementObject(objManagementScope, New ManagementPath(strJobPath), Nothing)
  48:              objJob.Get()
  49:              Do While objJob("JobState") = 3 Or objJob("JobState") = 4
  50:                  System.Threading.Thread.Sleep(1000)
  51:                  objJob.Get()
  52:              Loop
  53:              If objJob("JobState") <> 7 Then
  54:                  Console.WriteLine("ErrorCode=" & objJob("ErrorCode") & " JobState=" & objJob("JobState"))
  55:                  Return False
  56:              Else
  57:                  Return True
  58:              End If
  59:          Else
  60:              Return True
  61:          End If
  62:      End Function
  63:   
  64:  End Module


28行目:
VirtualNumaEnabledの値を設定します。NUMAを無効にするにはFalseに設定。

35-40行目:
ModifySystemSettingsメソッドで設定内容を変更する。


NUMAの設定方法が分かったところで、本題のメモリの設定方法です。基本的な設定項目は依然と同様となりますが、設定内容の変更はNUMAの設定変更同様「Msvm_VirtualSystemManagementService」クラスの「ModifySystemSettings」メソッドとなります。

 
   1:  Imports System.Management
   2:   
   3:  Module GMOReport
   4:   
   5:      Sub Main()
   6:          Dim strUser As String = ""
   7:          Dim strPass As String = ""
   8:          Dim objManagementScope As ManagementScope = ConnectManagementScope("win2012.local", strUser, strPass)
   9:          Call SetMemory(objManagementScope, "VM01", True, 1024, 512, 2048, 5000, 20)
  10:      End Sub
  11:   
  12:      Function ConnectManagementScope(ByVal strServer As String, ByVal strAccount As String, ByVal strPassword As String) As ManagementScope
  13:          Dim objConnectionOptions As New ConnectionOptions()
  14:          objConnectionOptions.Impersonation = ImpersonationLevel.Impersonate
  15:          objConnectionOptions.EnablePrivileges = True
  16:          objConnectionOptions.Username = strAccount
  17:          objConnectionOptions.Password = strPassword
  18:          Dim objManagementScope As New ManagementScope("\\" + strServer + "\root\virtualization\v2", objConnectionOptions)
  19:          objManagementScope.Connect()
  20:          Return (objManagementScope)
  21:      End Function
  22:   
  23:      Function SetMemory(ByVal objManagementScope As ManagementScope, ByVal strVMName As String, blnDynamicMemoryEnabled As Boolean, ByVal intVirtualQuantity As Integer, ByVal intReservation As Integer, ByVal intLimitMemory As Integer, ByVal intWeight As Integer, ByVal intTargetMemoryBuffer As Integer) As Boolean
  24:   
  25:          Dim objComputerSystem As ManagementObject = Nothing
  26:          For Each objManagementObject As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_ComputerSystem WHERE ElementName = '" & strVMName & "'")).Get
  27:              objComputerSystem = objManagementObject
  28:          Next
  29:   
  30:          Dim objVirtualSystemSettingData As ManagementObject = Nothing
  31:          For Each objManagementObject As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_VirtualSystemSettingData WHERE ElementName = '" & strVMName & "'")).Get
  32:              objVirtualSystemSettingData = objManagementObject
  33:          Next
  34:   
  35:          Dim objMemorySettingData As ManagementBaseObject = Nothing
  36:          For Each objManagementObject As ManagementObject In objVirtualSystemSettingData.GetRelated("Msvm_MemorySettingData")
  37:              objMemorySettingData = objManagementObject
  38:              objMemorySettingData("DynamicMemoryEnabled") = blnDynamicMemoryEnabled
  39:              objMemorySettingData("VirtualQuantity") = intVirtualQuantity
  40:              objMemorySettingData("Reservation") = intReservation
  41:              objMemorySettingData("Limit") = intLimitMemory
  42:              objMemorySettingData("Weight") = intWeight
  43:              objMemorySettingData("TargetMemoryBuffer") = intTargetMemoryBuffer
  44:          Next
  45:   
  46:          For Each objVirtualSystemManagementService As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_VirtualSystemManagementService")).Get
  47:              Dim objParams As ManagementBaseObject = objVirtualSystemManagementService.GetMethodParameters("ModifyResourceSettings")
  48:              objParams("ResourceSettings") = New String() {objMemorySettingData.GetText(TextFormat.CimDtd20)}
  49:              Dim objManagementBaseObject As ManagementBaseObject = objVirtualSystemManagementService.InvokeMethod("ModifyResourceSettings", objParams, Nothing)
  50:              Return JobComplete(objManagementBaseObject, objManagementScope)
  51:          Next
  52:      End Function
  53:   
  54:      Function JobComplete(ByVal objManagementBaseObject As ManagementBaseObject, ByVal objManagementScope As ManagementScope) As Boolean
  55:          'JobState New = 2  Starting = 3  Running = 4  Suspended = 5  ShuttingDown = 6  Completed = 7  Terminated = 8  Killed = 9  Exception = 10  Service = 11    
  56:          If objManagementBaseObject("ReturnValue") <> 0 Then
  57:              Dim strJobPath As String = objManagementBaseObject("Job")
  58:              Dim objJob As New ManagementObject(objManagementScope, New ManagementPath(strJobPath), Nothing)
  59:              objJob.Get()
  60:              Do While objJob("JobState") = 3 Or objJob("JobState") = 4
  61:                  System.Threading.Thread.Sleep(1000)
  62:                  objJob.Get()
  63:              Loop
  64:              If objJob("JobState") <> 7 Then
  65:                  Console.WriteLine("ErrorCode=" & objJob("ErrorCode") & " JobState=" & objJob("JobState"))
  66:                  Return False
  67:              Else
  68:                  Return True
  69:              End If
  70:          Else
  71:              Return True
  72:          End If
  73:      End Function
  74:   
  75:  End Module


VirtualQuantity スタートアップRAM
Reservation 最低RAM
Limit 最大RAM
TargetMemoryBuffer メモリバッファー(5~2000%)
Weight メモリの優先度(0~10000)
http://msdn.microsoft.com/en-us/library/cc136856(v=vs.85).aspx

今回のサンプルでは、最大メモリを2GB、最低メモリを512KBとして設定しています。このコードによってメモリの設定が可能となります。

以上、今回はWindows Server 2012 R2のHyper-Vから新たに追加されたDefineSystemメソッドによるVMの世代の設定方法と、メモリの設定方法をご紹介しました。

次回も引き続き新しいWMIの利用方法をご紹介します。






*本文中に記載されている会社名および商品名・サービス名は、各社の商標 または登録商標です。



樋口 勝一

GMOインターネット株式会社

1999年6月GMOインターネットに入社。Windowsを用いたホスティング事業の立ち上げの際、サービス開発からその後の保守・運用まで1人で担当。2010年には「お名前.comWindowsデスクトップ」をリリースし、マイクロソフト社と強い信頼関係を構築。2007年から連続で「マイクロソフトMVPアワード」を受賞し、Windowsのスペシャリストとして活躍。

執筆者一覧

 執筆協力した本が出版されました

 当レポートを担当しているGMOインターネット株式会社 事業本部 樋口 勝一が執筆協力をした書籍が出版されました。

Dynamic Memory
  最新!Android徹底活用読本

出版社:宝島社
価格:880円(税込) ※価格は店舗によって異なります。

次々に発売されるAndroidケータイを「コミュニケーションしたい」「情報をブラウジングしたい」「ビジネス手帳の代わりにしたい」「音楽や動画を120%楽しみたい」など、やりたいこと別に章立てした活用書。

Dynamic Memory
  GALAXY Sユーザーのためのアプリ245

出版社:三才ブックス
価格:1,260円(税込) ※価格は店舗によって異なります。

25万本以上あるといわれるAndroidアプリの中から、目的別・状況別に本当に使えるアプリだけを厳選。

Dynamic Memory
  ソニー・エリクソン公式 Xperia arc ガイドブック

出版社:日経BP社
価格:1,260円(税込) ※価格は店舗によって異なります。

こだわりのデザインと薄さを追求しながら、Androidスマートフォンのフラッグシップモデルとして世界に先駆けて日本で発売されるXperia arcの公式ガイドブックです。