GMOインターネット株式会社 事業本部 樋口 勝一が担当するGMO最新ネット業界レポート ソリューション編。『Hyper-Vを使ったクラウドサービスの作り方』として前回までにVol.1 Windows Server ライセンスの種類、使い方の紹介、Vol.2 Build to Orderな仮想マシンについてと紹介してきましたがVol.3となる今回は『Hyper-V Provisioning 仮想マシン一覧の取得』について紹介。
Hyepr-Vへのプログラムからのアプローチ方法
今回からはHyper-V Provisioningの基本を踏まえて、Hyepr-Vへのプログラムからのアプローチ方法をご紹介していきたいと思います。まず、Hyper-Vをプログラムで制御するにはWindows Management Instrumentation(WMI)を利用してアプローチすることになります。 (参考:Hyper-V WMI Classes )
クラス一覧を見てみると、Memory Class や Networking Class など仮想マシンに必要な各パーツがクラス分けされているのが分かります。これら各クラスを利用することで、例えばメモリ量の情報取得や、メモリの割り当てなどを行なうことができます。おおよそ全てのクラスに対し決まったパターンの構文でアプローチ可能となっているので、パターンを覚えてしまえば、その応用で様々なプログラムを作ることができるようになります。
サンプルコードをこちらからダウンロードいただけます。 → GMOReport.zip(15KB)
.NETのSystem.Management クラスを使ってWMIに接続
まずは、WMIの基本からです。.NETのSystem.Management クラスを使ってWMIに接続します。VisualStudioの参照設定で、System.Management を追加します。(参照:コード01)
コード1
1: Function ConnectManagementScope(ByVal strServer As String, ByVal
strAccount As String, ByVal strPassword As String) As ManagementScope
2: Dim objConnectionOptions As New ConnectionOptions()
3: objConnectionOptions.Impersonation = ImpersonationLevel.Impersonate
'WMI への接続に使用される偽装レベルを設定
4: objConnectionOptions.EnablePrivileges = True
'WNI経由の操作のためにユーザー特権を有効にする
5: objConnectionOptions.Username = strAccount
6: objConnectionOptions.Password = strPassword
7: Dim objManagementScope As New ManagementScope("\\" + strServer +
"\root\virtualization", objConnectionOptions)
8: objManagementScope.Connect()
9: Return (objManagementScope)
10: End Function
WMIへの接続のため、接続先のサーバー情報、セキュリティー情報を設定します。
3行目の Impersonation と4行目の EnablePrivileges でリモートからWMIを操作するため権限設定を行なっています。
このサンプルではリモートのサーバーに対しての接続設定となりますが、ローカルサーバーの場合、ConnectionOptions の設定が必要ありませんのでこのようにシンプルになります。(参照:コード02)
接続先のサーバー名も「.」で代用することができます。
コード2
1: Function ConnectManagementScope() As ManagementScope
2: Dim objManagementScope As New ManagementScope("\\.\root\virtualization")
3: objManagementScope.Connect()
4: Return (objManagementScope)
5: End Function
これでWMIに接続するための準備が完了しました。
Hyper-V上に搭載されている仮想マシンの一覧を取得するコード
次に、先ほど取得したManagementScope オブジェクトを使って実際にWMIを使って見ましょう。
簡単なところで、Hyper-V上に搭載されている仮想マシンの一覧を取得するコードをご紹介します。(参照:コード03)
コード3
1: SubGetVMList(ByVal objManagementScope As ManagementScope)
2: Dim objObjectQuery AsNew ObjectQuery("SELECT * FROM Msvm_ComputerSystem
WHERE Caption LIKE '仮想マシン'")
3: Dim objManagementObjectSearcher As New
ManagementObjectSearcher(objManagementScope, objObjectQuery)
4: Dim objManagementObjectCollection As
ManagementObjectCollection = objManagementObjectSearcher.Get
5: For Each objManagementObjectAs ManagementObject In
objManagementObjectCollection
6: Console.WriteLine(objManagementObject("ElementName"))
7: Next
8: End Sub
先ほど、取得したManagementScope オブジェクトを引数として渡します。
2行目:
WMIはSQLクエリ文のように目的のアイテムを抽出することができます。
4行目:
SELECT文で作成したたクエリオブジェクトを使用してManagementObjectCollectionを取得します。
5~7行目:
コレクションは複数のオブジェクトを返すので、For~Next文でそれぞれ単体のManagementObject として取得します。取得したManagementObjectは1つの仮想マシンに対応しているので、プロパティーのElementNameで仮想マシンの名前を知ることができます。コードを実行してみると、Hyper-V上に作成されている仮想マシンの名前の一覧が表示されます。
このように、ManagementScope オブジェクトを取得してクエリで抽出、ManagementObjectCollection をFor~Nextで回して目的のManagementObject を取得する、といった一連の流れがWMIを利用するお決まりのパターンとなります。
これを踏まえて、いよいよ実際に仮想マシンを作っていきましょう。 はじめは仮想マシンの骨組みとなる部分を作り、後からメモリやハードディスクなどを追加していきます。(参照:コード04)
コード4
1: Function DefineVM(ByVal objManagementScope As ManagementScope, ByVal
strVMName As String, ByVal strFolderPath As String) As Boolean
2: Dim objVirtualSystemGlobalsettingData As New
ManagementClass(objManagementScope, New ManagementPath
("Msvm_VirtualSystemGlobalsettingData"), Nothing)
3: Dim objVirtualSystemGlobalsettingDataInstance As ManagementObject =
objVirtualSystemGlobalsettingData.CreateInstance
4: objVirtualSystemGlobalsettingDataInstance("ElementName") = strVMName
5: objVirtualSystemGlobalsettingDataInstance("ExternalDataRoot") =
strFolderPath
6: Dim strSystemsettingData As String =
objVirtualSystemGlobalsettingDataInstance.GetText(TextFormat.CimDtd20)
7:
8: For Each objVirtualSystemManagementService As ManagementObject In New
ManagementObjectSearcher(objManagementScope, NewObjectQuery
("SELECT * FROM Msvm_VirtualSystemManagementService")).Get
9: Dim objParams As ManagementBaseObject =
objVirtualSystemManagementService.GetMethodParameters
("DefineVirtualSystem")
10: objParams("ResourceSettingData") = Nothing
11: objParams("Sourcesetting") = Nothing
12: objParams("SystemsettingData") = strSystemsettingData
13: Dim objManagementBaseObject As ManagementBaseObject =
objVirtualSystemManagementService.InvokeMethod
("DefineVirtualSystem", objParams, Nothing)
14: Return JobComplete(objManagementBaseObject, objManagementScope)
15: Next
16: End Function
17:
18: Function JobComplete(ByVal objManagementBaseObject As
ManagementBaseObject, ByVal objManagementScope As ManagementScope)
As Boolean
19: 'JobState New = 2 Starting = 3 Running = 4 Suspended = 5
ShuttingDown = 6 Completed = 7 Terminated = 8 Killed = 9
Exception = 10 Service = 11
20: If objManagementBaseObject("ReturnValue") <> 0 Then
21: Dim strJobPath As String = objManagementBaseObject("Job")
22: Dim objJob As New ManagementObject(objManagementScope, New
ManagementPath(strJobPath), Nothing)
23: objJob.Get()
24: Do While objJob("JobState") = 3 Or objJob("JobState") = 4
25: System.Threading.Thread.Sleep(1000)
26: objJob.Get()
27: Loop
28: If objJob("JobState") <> 7 Then
29: Console.WriteLine("ErrorCode=" & objJob("ErrorCode") & " JobState=" &
objJob("JobState"))
30: Return False
31: Else
32: Return True
33: End If
34: Else
35: Return True
36: End If
37: End Function
引数として渡すのは、ManagementScopeオブジェクト、仮想マシン名、仮想マシンの格納フォルダ となります。
2~3行目:
Msvm_VirtualSystemGlobalsettingDataクラスから仮想マシンを作成するための設定情報の新しいインスタンスを作成します。objVirtualSystemGlobalsettingData.CreateInstance は仮想マシンを作成しているわけではなく、仮想マシンの設定情報を新たに作成しているので、間違わないようにしてください。
4~5行目:
最低限の設定項目として、仮想マシン名と、仮想マシンを格納するフォルダパスを指定します。
6行目:設定情報としてXML形式で保存します。
8行目:
ここからちょっと難しくなりますが、これもパターンとして毎回出てくるので覚えておいてください。仮想マシンはMsvm_VirtualSystemManagementService クラスから作成したり、修正したり、削除することができます。Msvm_VirtualSystemManagementServiceクラスのオブジェクトを一つをFor~Next文で取り出します。
9行目:
仮想マシンを作成(定義)するためにはDefineVirtualSystemメソッドを使用することになります。事前にDefineVirtualSystemメソッドで必要となるパラメーターオブジェクトをGetMethodParametersで取得して、各項目に設定値を入力しておきます。
12行目:
先ほど仮想マシン名と仮想マシンの格納フォルダをXML化していた設定情報を、SystemsettingDataパラメーターに入力します。仮想マシンの骨組みを作成するのであれば、この設定内容だけで十分です。
13行目:
DefineVirtualSystemメソッドを、入力したパラメーターの内容で実行します。
14行目:
DefineVirtualSystemメソッドによって、仮想マシンが作成されることになるのですが、メソッドが実行される過程において、Hyper-V上では、刻々とステータスが変化してゆきます。最終的にはCompleted = 7 になれば成功となります。その過程でのエラーを正確に取得するため、Hyper-Vでメソッド実行時には毎回 JobCompleteを使うことにします。
以上で、エラー無くコードが走れば、Hyper-V上にはVM01という名前の仮想マシンが作成されているはずです。ですが、VM01の設定内容をみてみると、ハードディスクなどは接続されておらず、512MBのメモリと1個の仮想プロセッサが割り当てられているだけとなっています。
ここから、いろいろなオプションを付け足して本来必要な仮想マシンを作り上げていくことになります。
次回以降は、ハードディスクを初めとしたオプションの追加方法をご紹介する予定です。
サンプルコードをこちらからダウンロードいただけます。 → GMOReport.zip(15KB)
*本文中に記載されている会社名および商品名・サービス名は、各社の商標 または登録商標です。