WIN1@Codename

Codename

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

ReFS上のNTFSフォーマットのvhdxファイルは、ReFSの速さとNTFSの使い勝手を実装する

新しいファイルフォーマットのReFSは、Hyper-Vで利用する場合NTFSと比べて利点もありますが、NTFSでできたことが一部できないなど、使い勝手で用途を選ぶ必要があります。

ReFSの利点
・ファイルデーターの破損を確実に検出
・オンラインで破損ファイルの修復が可能
・ファイルが使用する物理ディスク内の領域(論理セクター)をメタデータで管理
・ファイルをコピーする場合、メタデータの操作(論理クラスターの割当と変更)で完結し、物理データの操作は不要
・容量固定のvhdxファイルの作成が速い
・チェックポイントの削除(ファイルの結合)が速い

ReFSとNTFSの比較
20175625110602.jpg


ですが、vhdxファイルをうまく使うことで、ReFSの利点とこれまでのNTFSの使い勝手を同時に利用することができるようになります。

サーバー上の物理ドライブとしてEドライブがReFSでフォーマットされています。
20175225110612.jpg

Eドライブ内にNTFSフォーマットの容量固定10GBの仮想ハードディスクを作成します。
かかった時間はわずか2秒ちょっと。ReFSなので速いです。
20170625120603.jpg


作成したvhdxファイルをサーバーにマウントして、Fドライブとします。
20170925120617.jpg

通常であればNTFSフォーマット上で、vhdxディスクファイルを容量固定で作成するとそれなりの時間が必要となりますが、ReFS上のvhdxファイルをNTFSでフォーマットすることで、ReFSのパフォーマンを持ったNTFSフォーマットのドライブとして利用することができます。

Fドライブ上に容量固定で5GBのvhdxファイルを作成してみましょう。
201714251206070.jpg
2.4秒ほどで作成されました。

通常のNTFSドライブでは
20173025120628.png
3分以上かかりますね。

以上、ということで、ReFSとNTFSは使い方次第で利用価値が大きく広がります。




スポンサーサイト

Hyper-V上で稼働中の仮想マシンのVHDを使って、物理マシンでVHDブートする方法メモ (これも「V to P」?) 追記 2

VHDブートするvhdファイルは必ずベーッシクディスクドライブに置くこと!

ダイナミックディスク上に置いたvhdファイルだと、bcdedit /set  でエラーになります。

Windows Update 後に sysprep を実行したら「致命的なエラーが発生しました」の対処方法

しばらくWindowsUpdateを行っていなかった仮想マシンに、まとめてWindowsUpdateを実施しました。

かなりの数のアップデートがありまつことしばし。

その後、この仮想マシンのイメージをコピーして、sysprepを実行したところ、「致命的なエラーが発生しました」とのこと。

20150122050450

sysprepのログを見てみると

"C:\Windows\System32\Sysprep\Panther\setuperr.log"
[0x0f0073] SYSPRP RunExternalDlls:Not running DLLs; either the machine is in an invalid state or we couldn't update the recorded state, dwRet = 0x1f
[0x0f00ae] SYSPRP WinMain:Hit failure while processing sysprep cleanup external providers; hr = 0x8007001f

slmgr -dlv コマンドでリセット回数を確認しても、問題ありません。
20155622070433

skiprearm をsysprepの応答ファイルにいれて、sysprepの3回という制限は解除しているのですが、このエラーを解消するためには、sysprepの回数制限でエラーが起きた場合の対処方法と同じ処方が必要となります。

1.2つのレジストリを下記の内容に編集します。
HKEY_LOCAL_MACHINE\SYSTEM\Setup\Status\SysprepStatus\GeneralizationState\CleanupState:2
HKEY_LOCAL_MACHINE\SYSTEM\Setup\Status\SysprepStatus\GeneralizationState\GeneralizationState:7

2.コマンドプロンプトで下記の2つのコマンドを実行します。
msdtc –uninstall
msdtc –install

3.再起動します。

4.改めてsysprepを実行します。

これで「致命的なエラー・・」が発生しなければ成功です!

VHDの多様化する利用方法

大容量仮想ハードディスクからのブート

新しいHyper-Vとともに、仮想ハードディスクの機能やパフォーマンスもあわせて向上しています。仮想ハードディスク自体の読み取り、書き込み速度は、物理ハードディスクの性能とほぼ変わらないものとなっています。新しい仮想ハードディスク形式の「.vhdx」ファイルでは最大64TBまで作成することが可能になりました。

前回のレポートに登場した「UEFI」との組み合わせで、最大64TBのハードディスクからブートが可能になりました。このほかにもvhd(以降vhdxファイルを含む)ファイルを利用した様々な機能をご紹介します。

VHDファイルのマウント・アンマウント

Windows Server 2008 R2から、vhdファイルをWindowsの一つのドライブとしてマウントして利用することはできたのですが、PowerShellやdiskpartコマンド、スクリプトなどを利用するか、「コンピューターの管理」ツール - 「ディスクの管理」から「VHDの接続」を選択するなど、なかなか操作が面倒でした。

Windows Server 2012 からは、vhdファイルのマウント、アンマウントが簡単にできるようになりました。マウントをしたいvhdファイルをマウスで右クリックして「マウント」を選択するか、vhdファイル自体をダブルクリックするだけです。

事前にフォーマット済みのvhdファイルであれば、一瞬でマウントが完了し追加ドライブとして利用できます。

反対にマウントを解除する場合は、エクスプローラーから該当ドライブを右クリックで選択して「取り出し」を選択すればOKです。

事前にフォーマットをしていないvhdファイルをマウントしようとした場合は、フォーマットを促すメッセージが表示されますので、「コンピューターの管理」ツール - 「ディスクの管理」からフォーマットを実行してください。一度フォーマットしておけば、以後アラートは表示されません。

参考までにPowerShellのコマンドは以下となります。(管理者権限で実行)

Mount-VHD "D:\MyDisk.vhdx"
Dismount-VHD "D:\MyDisk.vhdx"

仮想マシン実行時でもディスク領域の拡張・縮小が可能に

仮想マシンに割り当てたvhdファイルをHyper-V上で仮想マシンが実行中であっても、vhdファイルのディスク領域の拡張、縮小が可能になりました。仮想マシンの設定メニューから、ハードディスクを選択して「編集」ボタンをクリックします。

「縮小」については、vhdファイルに縮小可能な領域があるときのみ、選択可能です。vhdファイルをHyper-Vマネージャーの「拡張」メニューを使って行った場合は、仮想マシンにログインした後、「コンピューターの管理」ツール - 「ディスクの管理」から「ボリュームの拡張」を選択することで、すぐに仮想マシンから拡張領域を利用することが可能になります。

VHDブートのすすめ

仮想ハードディスクのパフォーマンスの向上は、仮想マシンだけではなく、物理マシンのvhdブートでも顕著にあらわれています。VHDブートは、物理マシンを物理ディスク内のvhdファイルから起動する機能です。サーバーやPCの検証用などのマルチブート環境を簡単に構築できるといったメリットだけではなく、複数のクローンサーバーの展開や、バックアップ、リストアの簡略化にも有効な手段です。また、いくつか制限があるものの、Hyper-V上で作成した仮想マシンのvhdファイルを利用して、物理サーバーやノートPCへのV2P(仮想マシンから物理マシンへのシステム移行)にも利用できます。以下に具体的なvhdブートの設定方法を紹介します。
一番簡単だと思われる方法は、現在起動中のWindowsからvhdファイルを作成して、OSのインストールディスクから物理マシンを起動しvhdブート用のOSをインストールする方法です。まずは、vhdブート用のvhdファイルを作成します。「コンピューターの管理」ツール - 「ディスクの管理」から「vhdの作成」を選択します。

今回作成したvhdファイルは以下の通りです。

次にWindowsのインストールメディアを用意します。今回はWindows Server 2012R2のものを用意しました。物理マシンをインストールメディアから起動して、インストールメニューを表示させ「コンピューターを修復する」を選択します。

次に、「オプションの選択」から「トラブルシューティング」を選択します。

続いて「コマンドプロンプト」を選択して、表示させます。

コマンドは次の通り。

diskpart
list vol
select vdisk file=C:\VHDBoot.vhdx
attach vdisk
exit
setup

最後の「setup」コマンドでインストールが再開します。

インストール場所として、「割り当てられていない領域」と表示されている、アタッチしたvhdファイルにOSをインストールします。

インストールが完了すると、Windows Server の場合はこちらのWindows ブートマネージャーが起動します。

規定値ではブート名が既存のOS名と同じなので、OS起動完了後、ログインして、コマンドプロンプトを管理者権限で開き、「bcdedit」コマンドで設定変更することができます。今回は以下の設定にします。

bcdedit /set description "Windows Server 2012 R2 VHDBoot"

これでvhdブートの設定が完了です。
vhdブートの設定を削除する場合は、ブートマネージャーから削除するブートOS以外を選択して、OSを起動します。起動完了後、コマンドプロンプトを管理者権限で開き「msconfig」コマンドで、「システム構成」を起動します。「ブート」タブから、通常のブートOSを選択して、「既定値に設定する」を選択します。ブートの既定値が変更された状態で、vhdブートのOSを削除することができます。vhdファイルも不要でれば、ファイル自体を削除すれば完全にvhdブート環境を削除することが可能です。

VHDブートでV2P

上記のvhdブートの仕組みを利用し、既存の仮想マシンのvhdファイルを使って、物理マシンへシステム移行してみます。第2世代の仮想マシンのvhdファイルを利用する場合は、物理マシンが「UEFI」と「SCSIブート」をサポートしている必要があります。今回は一般的な「BIOS」と「IDEブート」をサポートしている第1世代の仮想マシンのvhdファイルを利用してV2Pを行ってみます。まずはvhdブートの設定を行う物理マシンに仮想マシンのvhdファイルをコピーします。続けて管理者権限でコマンドプロンプトを開き、以下のコマンドを実行します。

takeown /F "C:\VM01.vhdx"
bcdedit /copy {current} /d "VM01"

(注)"VM01"は起動時に表示される名前なので任意で指定可能

実行後、「エントリは{*****-*****-*****}に正しくコピーされました。」と実行結果が表示されるので、カッコも含めて {*****-*****-*****} をコピーする。
今回は {1b645280-3955-11e3-b9d1-b8f35ef6360f} となります。

bcdedit /set {1b645280-3955-11e3-b9d1-b8f35ef6360f} device vhd=[C:]\VM01.vhdx 

(注)C:\ VM01.vhdx のパス指定が [C:]\VM01.vhdx となる。

bcdedit /set {1b645280-3955-11e3-b9d1-b8f35ef6360f} device vhd=[C:]\VM01.vhdx 

コマンド実行後再起動すると、ブートOSの選択画面となるので、vhdブートしたいOSを選択します。

物理マシンの構成によっては、起動後にドライバの再設定などが必要になる場合がありますので、不足しているディスプレイドライバやネットワークドライバをダウンロードしてインストールする必要があります。これでV2Pの完了となります。

共有仮想ハードディスク

「共有仮想ハードディスク」は、Hyper-V上の仮想マシンでWindows Server の機能の一つ、「フェールオーバークラスタ」を構築する場合に利用することができます。これまでは、仮想マシンごとに「iSCSIイニシエーター」の設定を行い、iSCSI仮想ディスクを作成し、接続するといった、面倒な設定作業が必要でした。この作業を「共有仮想ハードディスク」を利用することで簡単に構築設定することができるようになりました。
大まかな接続設定は、スケールアウトファイルサーバー(SOFS)と呼ばれる高可用性ストレージ上の共有領域に、「共有仮想ハードディスク」としてvhdファイルを保存するだけです。各クラスタノードとなる仮想マシンは、このvhdファイルにUNCパスで接続します。

「高度な機能」で「仮想ハードディスクの共有を有効にする」にチェックを入れます。これだけでクラスタ用の共有ディスク領域として利用することができるようになります。

仮想マシンで構築する「フェールオーバークラスタ」については、別の回で構築方法から詳しく紹介したいと思います。

以上、今回はHyper-Vの進化とともに、仮想ハードディスクも進化し、利用方法が拡大しているポイントをご紹介しました。仮想マシンのハードディスクとしてだけで使うには、有り余る機能があるVHDです。是非ご利用ください。

Hyper-V上での仮想マシンのエクスポートとインポート

Hyper-Vのエクスポートとインポート機能

Windows Server 2012 のHyper-Vからは、仮想マシンが稼働中であってもエクスポートが可能となり、仮想マシンをエスポーとすることなく、直接仮想マシンフォルダからインポートもできるようになりました。

とても便利になったHyper-Vのエクスポートとインポート機能ですが、インポートする場合では、新しい root\virtualization\v2 名前空間では少々手順が複雑化しており、
新しいメソッド「ImportSystemDefinition」を実行するだけではVMのインポートは完了せず、設定ファイルだけが作成されるだけとなっています。

新しいHyper-Vで、エクスポートから一通りのインポート作業が完了するまでの手順をご紹介します。

仮想マシンののエクスポート

WMI経由で仮想マシンのエクスポートを行う場合は、Msvm_VirtualSystemExportSettingDataクラスを使用します。
実際にコード内でMsvm_VirtualSystemExportSettingDataクラスでプロパティーを指定して、ExportSystemDefinition メソッドで実行します。

Msvm_VirtualSystemExportSettingDataクラスのプロパティーは以下となります。

CopySnapshotConfiguration エクスポートする場合にスナップショットを含めるか否か。(Windows Server 2012R2 からは「スナップショット」は「チェックポイント」とう名前に変更されました。)
全てのスナップショットを含める(ExportAllSnapshots)= 0
スナップショットを含まない(ExportNoSnapshots)= 1
スナップショットの一つをエクスポート(ExportOneSnapshot)= 2
※仮想マシンのスナップショットの1つだけを指定してエクスポートもできます。
CopyVmRuntimeInformation 仮想マシンが保存された状態である場合にメモリ内容をエクスポートするか否か。メモリ内容が無い状態でインポートを実行すると、保存状態は破棄され停止状態で仮想マシンはインポートされます。
CopyVmStorage エクスポートに仮想ハードディスクを含めるか否か。
CreateVmExportSubdirectory サブディレクトリを作成するか否か。
SnapshotVirtualSystem CopySnapshotConfiguration で ExportOneSnapshot(=2)を選択した場合に、エクスポートするスナップショットの Msvm_VirtualSystemSettingData クラスを指定する。

これらを踏まえた仮想マシンのエクスポートのサンプルコードは以下となります。


   1:  Imports System.Management
   2:   
   3:  Module GMOReport
   4:      Sub Main()
   5:          Dim strUser As String = ""
   6:          Dim strPass As String = ""
   7:          Dim objManagementScope As ManagementScope = ConnectManagementScope("WinSvr2012R2", strUser, strPass)
   8:          objManagementScope.Connect()
   9:   
  10:          Dim strVMName As String = "VM01"
  11:   
  12:          Call ExportVm(objManagementScope, strVMName, 0, True, True, True, "D:\Hyper-V\Exp", "")
  13:      End Sub
  14:   
  15:      Function ConnectManagementScope(ByVal strServer As String, ByVal strAccount As String, ByVal strPassword As String) As ManagementScope
  16:          Dim objConnectionOptions As New ConnectionOptions()
  17:          objConnectionOptions.Impersonation = ImpersonationLevel.Impersonate 'WMI への接続に使用される偽装レベルを設定
  18:          objConnectionOptions.EnablePrivileges = True 'WNI経由の操作のためにユーザー特権を有効にする
  19:          objConnectionOptions.Username = strAccount
  20:          objConnectionOptions.Password = strPassword
  21:          Dim objManagementScope As New ManagementScope("\\" + strServer + "\root\virtualization\v2", objConnectionOptions)
  22:          objManagementScope.Connect()
  23:          Return (objManagementScope)
  24:      End Function
  25:   
  26:      Function ExportVm(ByVal objManagementScope As ManagementScope, strVMName As String, intCopySnapshotConfiguration As Integer, blnCopyVmRuntimeInformation As Boolean, blnCopyVhd As Boolean, blnCreateSubdirectory As Boolean, ByVal strExportDirectory As String, strSnapshotName As String) As Boolean
  27:          Dim objComputerSystem As ManagementObject = Nothing
  28:          For Each objManagementObject As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_ComputerSystem WHERE ElementName = '" & strVMName & "'")).Get
  29:              objComputerSystem = objManagementObject
  30:          Next
  31:   
  32:          Dim objVirtualSystemsettingData As ManagementObject = Nothing
  33:          If strSnapshotName <> "" Then
  34:              For Each objManagementObject As ManagementObject In objComputerSystem.GetRelated("Msvm_VirtualSystemSettingData")
  35:                  If objManagementObject("ElementName") = strSnapshotName Then
  36:                      objVirtualSystemsettingData = objManagementObject
  37:                      Exit For
  38:                  End If
  39:              Next
  40:          End If
  41:   
  42:          Dim objVirtualSystemExportSettingData As New ManagementClass(objManagementScope, New ManagementPath("Msvm_VirtualSystemExportSettingData"), Nothing)
  43:          Dim objVirtualSystemExportSettingDataInstance As ManagementObject = objVirtualSystemExportSettingData.CreateInstance
  44:          objVirtualSystemExportSettingDataInstance("CopySnapshotConfiguration") = intCopySnapshotConfiguration 'ExportAllSnapshots:0 ExportNoSnapshots:1 ExportOneSnapshot:2
  45:          objVirtualSystemExportSettingDataInstance("CopyVmRuntimeInformation") = blnCopyVmRuntimeInformation
  46:          objVirtualSystemExportSettingDataInstance("CopyVmStorage") = blnCopyVhd
  47:          objVirtualSystemExportSettingDataInstance("CreateVmExportSubdirectory") = blnCreateSubdirectory
  48:          objVirtualSystemExportSettingDataInstance("SnapshotVirtualSystem") = objVirtualSystemsettingData
  49:          Dim strExportSettingData As String = objVirtualSystemExportSettingDataInstance.GetText(TextFormat.CimDtd20)
  50:   
  51:          For Each objVirtualSystemManagementService As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_VirtualSystemManagementService")).Get
  52:              Dim objParams As ManagementBaseObject = objVirtualSystemManagementService.GetMethodParameters("ExportSystemDefinition")
  53:              objParams("ComputerSystem") = objComputerSystem.Path.Path
  54:              objParams("ExportDirectory") = strExportDirectory
  55:              objParams("ExportSettingData") = strExportSettingData
  56:              Dim objManagementBaseObject As ManagementBaseObject = objVirtualSystemManagementService.InvokeMethod("ExportSystemDefinition", objParams, Nothing)
  57:              Return JobComplete(objManagementBaseObject, objManagementScope)
  58:          Next
  59:      End Function
  60:   
  61:      Function JobComplete(ByVal objManagementBaseObject As ManagementBaseObject, ByVal objManagementScope As ManagementScope) As Boolean
  62:          'JobState New = 2  Starting = 3  Running = 4  Suspended = 5  ShuttingDown = 6  Completed = 7  Terminated = 8  Killed = 9  Exception = 10  Service = 11
  63:          If objManagementBaseObject("ReturnValue") <> 0 Then
  64:              Dim strJobPath As String = objManagementBaseObject("Job")
  65:              Dim objJob As New ManagementObject(objManagementScope, New ManagementPath(strJobPath), Nothing)
  66:              objJob.Get()
  67:              Do While objJob("JobState") = 3 Or objJob("JobState") = 4
  68:                  System.Threading.Thread.Sleep(1000)
  69:                  objJob.Get()
  70:              Loop
  71:              If objJob("JobState") <> 7 Then
  72:                  Console.WriteLine("ErrorCode=" & objJob("ErrorCode") & " JobState=" & objJob("JobState"))
  73:                  Return False
  74:              Else
  75:                  Return True
  76:              End If
  77:          Else
  78:              Return True
  79:          End If
  80:      End Function
  81:  End Module


エクスポートが成功すると、このようにスナップショットも含めてファオルダが作成されます。


仮想マシンのインポート

次にインポートです。先にも述べましたが、root\virtualization\v2 名前空間ではインポートがいくつかのステップによって実行されます。大まかな流れとしてはこのようになります。Hyper-V マネージャーの仮想マシンのインポートウィザードとほぼ同じ手順となります。

1. 仮想マシンをインポートするための設定ファイルを読み込み、実行するインポートの種類を指定する
ImportSystemDefinition


2. 仮想マシンの保存場所の設定
ModifySystemSettings


3. ハードディスクの保存場所の設定
ModifyResourceSettings


4. インポート設定の検証
ValidatePlannedSystem


5. インポートの実行
RealizePlannedSystem

6. インポート構成ファイルの削除
DestroySystem


1. 仮想マシンをインポートするための設定ファイルを読み込む

仮想マシンをインポートするためには、Definition Fileと呼ばれるxmlの構成ファイルを読み込む必要があります。通常は、仮想マシンフォルダやエクスポートした仮想マシンフォルダの中の、「Virtual Machines」フォルダに 1D5E37BD-202C-4B76-B8C1-F4CFD3B67313.XML といったようなファイル名で保存されています。

Msvm_VirtualSystemManagementService クラスのImportSystemDefinition メソッドで各パラメーターを指定して実行します。

SystemDefinitionFile構成ファイルのフルパスを指定します。
SnapshotFolderエクスポートした仮想マシンにスナップショットがある場合に、スナップショットの構成ファイル(xml)があるフォルダを指定します。
GenerateNewSystemIdentifier「実行するインポートの種類」のうち、「仮想マシンをインプレースで登録する(既存の一意なIDを使用する)」「仮想マシンを復元する(既存の一意なIDを使用する)」を選択した場合は「False」を、「仮想マシンをコピーする(新しい一意なIDを作成する)」の場合は「True」を指定します。

仮想マシンの設定ファイルの読み込みが成功すると、"C:\ProgramData\Microsoft\Windows\Hyper-V\Planned Virtual Machines" フォルダに、インポート候補の構成ファイルが作成されます。

以降の操作対象となるのは、仮想マシンではなく、インポート候補となっている仮想マシンが対象となります。

そのため、これまでは
 SELECT * FROM Msvm_ComputerSystem
としていた操作対象となる仮想マシンの指定部分が
 SELECT * FROM Msvm_PlannedComputerSystem
と変更になっている点に注意が必要です。

2. 仮想マシンの保存場所の設定

インポートする時に仮想マシンのフォルダ構成を変更することができます。エクスポートファイルをバックアップとしてのリストアを行う場合は問題ありませんが、エクスポートファイルから仮想マシンのクローンを作る場合などはこの設定が必要となります。

エクスポートした仮想マシンの構成ファイルには、元々の仮想マシンの構成フォルダなどのパスが記載されており、エクスポート元の仮想マシンと同一の構成内容となっています。そのため、そのままインポートしてしまうと、パスなどが競合してしまうこととなるので、変更が必要となります。

変更対象となるのは、先ほど構成ファイルを読み込み、"C:\ProgramData\Microsoft\Windows\Hyper-V\Planned Virtual Machines" フォルダに保存された、インポート候補の構成ファイルとなります。

こちらの構成ファイルをMsvm_VirtualSystemSettingDataクラスのプロパティーを指定して、ModifySystemSettings メソッドで変更します。

Msvm_VirtualSystemSettingData クラスのプロパティーは以下となります。

ConfigurationDataRoot仮想マシンの構成フォルダ
SnapshotDataRootチェックポイント ストア
SwapFileDataRootスマート ページング フォルダ

今回は仮想マシンの構成フォルダを、すべてのフォルダパスとしています。


3. ハードディスクの保存場所の設定

仮想マシンの保存場所の設定変更同様に、仮想ハードディスクのパスも変更する必要があります。また、指定するパスに仮想ハードディスクファイル(vhdx)や、スナップショットファイル(avhdx)が事前に配置されている必要があります。エクスポートフォルダ内から、該当フォルダにファイルをコピーもしくは、移動をしておきます。

Msvm_StorageAllocationSettingDataクラスのプロパティーを指定して、ModifyResourceSettings メソッドで変更します。変更するMsvm_StorageAllocationSettingDat クラスのプロパティーは以下となります。

HostResourcet仮想ハードディスクのファイルパスを指定します。

今回は仮想マシンの構成フォルダをルートパスとしています。

スナップショットのファイル(avhdx)パスについては、「1.ImportSystemDefinition」でスナップショットの構成フォルダを指定することで、自動的にパスを書き換えてくるので、設定変更の必要はありません。


4. インポート設定の検証

"C:\ProgramData\Microsoft\Windows\Hyper-V\Planned Virtual Machines" フォルダに保存された、インポート候補の構成ファイルをインポートを実行する前に事前に問題がないか検証を行います。

XMLのファイル構文や、仮想ハードディスクのパスが有効なものであるか否かなどが検証対象となります。Msvm_VirtualSystemManagementService クラスの ValidatePlannedSystem メソッドで検証を実行します。


5. インポートの実行

インポート設定の検証に問題がなければ、最実際の仮想マシンとしてHyper-V上にインポートを実行します。

"Msvm_VirtualSystemManagementService クラスの RealizePlannedSystem メソッドで実行します。


6. インポート構成ファイルの削除

読み込んだインポート構成ファイルを削除して完了となります。Msvm_VirtualSystemManagementService クラスの DestroySystem メソッドで実行します。

エクスポートファイルからクローンを作成する場合は、仮想マシンの名前も変更する必要があるので、仮想マシンの名前の変更方法も追記しておきます。
こちらは、インポートした仮想マシンのIDを元に名前変更を行っています。

実行結果は、このように仮想マシンのクローンとしてインポートが完了しました。


以上を踏まえて、仮想マシンのインポートの一通りの手順のサンプルコードを紹介します。


   1:  Imports System.Management
   2:   
   3:  Module GMOReport
   4:      Sub Main()
   5:          Dim strUser As String = ""
   6:          Dim strPass As String = ""
   7:          Dim objManagementScope As ManagementScope = ConnectManagementScope("WinSvr2012R2", strUser, strPass)
   8:          objManagementScope.Connect()
   9:   
  10:          Dim strVMName As String = "VM01"
  11:   
  12:          Call ImportVm(objManagementScope, True, "VM01", "D:\Hyper-V\Exp\VM01\Virtual Machines\1D5E37BD-202C-4B76-B8C1-F4CFD3B67313.XML", "D:\Hyper-V\Exp\VM01\Snapshots", "D:\Hyper-V\VM02", "D:\Hyper-V\VM02", "VM02")
  13:      End Sub
  14:   
  15:      Function ConnectManagementScope(ByVal strServer As String, ByVal strAccount As String, ByVal strPassword As String) As ManagementScope
  16:          Dim objConnectionOptions As New ConnectionOptions()
  17:          objConnectionOptions.Impersonation = ImpersonationLevel.Impersonate 'WMI への接続に使用される偽装レベルを設定
  18:          objConnectionOptions.EnablePrivileges = True 'WNI経由の操作のためにユーザー特権を有効にする
  19:          objConnectionOptions.Username = strAccount
  20:          objConnectionOptions.Password = strPassword
  21:          Dim objManagementScope As New ManagementScope("\\" + strServer + "\root\virtualization\v2", objConnectionOptions)
  22:          objManagementScope.Connect()
  23:          Return (objManagementScope)
  24:      End Function
  25:   
  26:   
  27:      Function ImportVm(ByVal objManagementScope As ManagementScope, ByVal blnNewId As Boolean, strVMName As String, ByVal strImportConfigFilePath As String, strImportSnapshotFolder As String, strVMRootPath As String, strDiskRootPath As String, strNewVMName As String) As Boolean
  28:          Dim strRealizedVmId As String = ""
  29:          If ImportVmConfig(objManagementScope, strImportConfigFilePath, strImportSnapshotFolder, blnNewId) Then
  30:              If ChangePlannedConfig(objManagementScope, strVMName, strVMRootPath) Then
  31:                  If ChangePlannedHardDisk(objManagementScope, strVMName, strDiskRootPath) Then
  32:                      If ValidatePlannedVm(objManagementScope, strVMName) Then
  33:                          If RealizePlannedVm(objManagementScope, strVMName, strRealizedVmId) Then
  34:                              If RenameVM(objManagementScope, strRealizedVmId, strVMName, strNewVMName) Then
  35:                                  Return True
  36:                              End If
  37:                          End If
  38:                      End If
  39:                  End If
  40:              End If
  41:          End If
  42:          Call DeletePlannedVm(objManagementScope, strVMName)
  43:          Return False
  44:      End Function
  45:   
  46:      Function ImportVmConfig(ByVal objManagementScope As ManagementScope, ByVal strSystemDefinitionFilePath As String, strSnapshotFolder As String, ByVal blnNewId As Boolean) As Boolean
  47:          For Each objVirtualSystemManagementService As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_VirtualSystemManagementService")).Get
  48:              Dim objParams As ManagementBaseObject = objVirtualSystemManagementService.GetMethodParameters("ImportSystemDefinition")
  49:              objParams("SystemDefinitionFile") = strSystemDefinitionFilePath
  50:              objParams("SnapshotFolder") = strSnapshotFolder
  51:              objParams("GenerateNewSystemIdentifier") = blnNewId
  52:              Dim objManagementBaseObject As ManagementBaseObject = objVirtualSystemManagementService.InvokeMethod("ImportSystemDefinition", objParams, Nothing)
  53:              Return JobComplete(objManagementBaseObject, objManagementScope)
  54:          Next
  55:      End Function
  56:   
  57:      Function ValidatePlannedVm(ByVal objManagementScope As ManagementScope, ByVal strVMName As String) As Boolean
  58:          Dim objComputerSystem As ManagementObject = Nothing
  59:          For Each objManagementObject As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_PlannedComputerSystem WHERE ElementName = '" & strVMName & "'")).Get
  60:              objComputerSystem = objManagementObject
  61:          Next
  62:          For Each objVirtualSystemManagementService As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_VirtualSystemManagementService")).Get
  63:              Dim objParams As ManagementBaseObject = objVirtualSystemManagementService.GetMethodParameters("ValidatePlannedSystem")
  64:              objParams("PlannedSystem") = objComputerSystem.Path.Path
  65:              Dim objManagementBaseObject As ManagementBaseObject = objVirtualSystemManagementService.InvokeMethod("ValidatePlannedSystem", objParams, Nothing)
  66:              Return JobComplete(objManagementBaseObject, objManagementScope)
  67:          Next
  68:      End Function
  69:   
  70:      Function RealizePlannedVm(ByVal objManagementScope As ManagementScope, ByVal strVMName As String, ByRef strRealizedVmId As String) As Boolean
  71:          Dim objComputerSystem As ManagementObject = Nothing
  72:          For Each objManagementObject As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_PlannedComputerSystem WHERE ElementName = '" & strVMName & "'")).Get
  73:              objComputerSystem = objManagementObject
  74:          Next
  75:          For Each objVirtualSystemManagementService As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_VirtualSystemManagementService")).Get
  76:              Dim objParams As ManagementBaseObject = objVirtualSystemManagementService.GetMethodParameters("RealizePlannedSystem")
  77:              objParams("PlannedSystem") = objComputerSystem.Path.Path
  78:              Dim objManagementBaseObject As ManagementBaseObject = objVirtualSystemManagementService.InvokeMethod("RealizePlannedSystem", objParams, Nothing)
  79:              Call JobComplete(objManagementBaseObject, objManagementScope)
  80:   
  81:              Dim objJob As New ManagementObject(objManagementBaseObject("Job").ToString())
  82:              objJob.Scope = objManagementScope
  83:              objJob.Get()
  84:              For Each objManagementObject As ManagementObject In objJob.GetRelated("Msvm_ComputerSystem")
  85:                  strRealizedVmId = objManagementObject("Name")
  86:              Next
  87:              Return True
  88:          Next
  89:      End Function
  90:   
  91:      Function DeletePlannedVm(ByVal objManagementScope As ManagementScope, ByVal strVMName As String) As Boolean
  92:          Dim objComputerSystem As ManagementObject = Nothing
  93:          For Each objManagementObject As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_PlannedComputerSystem WHERE ElementName = '" & strVMName & "'")).Get
  94:              objComputerSystem = objManagementObject
  95:          Next
  96:          For Each objVirtualSystemManagementService As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_VirtualSystemManagementService")).Get
  97:              Dim objParams As ManagementBaseObject = objVirtualSystemManagementService.GetMethodParameters("DestroySystem")
  98:              objParams("AffectedSystem") = objComputerSystem.Path.Path
  99:              Dim objManagementBaseObject As ManagementBaseObject = objVirtualSystemManagementService.InvokeMethod("DestroySystem", objParams, Nothing)
 100:              Return JobComplete(objManagementBaseObject, objManagementScope)
 101:          Next
 102:      End Function
 103:   
 104:      Function ChangePlannedConfig(ByVal objManagementScope As ManagementScope, ByVal strVMName As String, ByVal strRootPath As String) As Boolean
 105:          Dim objComputerSystem As ManagementObject = Nothing
 106:          For Each objManagementObject As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_PlannedComputerSystem WHERE ElementName = '" & strVMName & "'")).Get
 107:              objComputerSystem = objManagementObject
 108:          Next
 109:   
 110:          Dim objVirtualSystemsettingData As ManagementObject = Nothing
 111:          For Each objManagementObject As ManagementObject In objComputerSystem.GetRelated("Msvm_VirtualSystemSettingData")
 112:              If String.Compare(objManagementObject("ElementName").ToString, strVMName, True) = 0 Then
 113:                  objVirtualSystemsettingData = objManagementObject
 114:                  objVirtualSystemsettingData("ConfigurationDataRoot") = strRootPath
 115:                  objVirtualSystemsettingData("SnapshotDataRoot") = strRootPath
 116:                  objVirtualSystemsettingData("SwapFileDataRoot") = strRootPath
 117:              End If
 118:          Next
 119:   
 120:          For Each objVirtualSystemManagementService As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_VirtualSystemManagementService")).Get
 121:              Dim objParams As ManagementBaseObject = objVirtualSystemManagementService.GetMethodParameters("ModifySystemSettings")
 122:              objParams("SystemSettings") = objVirtualSystemsettingData.GetText(TextFormat.CimDtd20)
 123:              Dim objManagementBaseObject As ManagementBaseObject = objVirtualSystemManagementService.InvokeMethod("ModifySystemSettings", objParams, Nothing)
 124:              Return JobComplete(objManagementBaseObject, objManagementScope)
 125:          Next
 126:      End Function
 127:   
 128:      Function ChangePlannedHardDisk(ByVal objManagementScope As ManagementScope, ByVal strVMName As String, ByVal strDiskRootPath As String) As Boolean
 129:          Dim objComputerSystem As ManagementObject = Nothing
 130:          For Each objManagementObject As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_PlannedComputerSystem WHERE ElementName = '" & strVMName & "'")).Get
 131:              objComputerSystem = objManagementObject
 132:          Next
 133:   
 134:          Dim objHardDisk As ManagementObject = Nothing
 135:          Dim objVirtualSystemsettingData As ManagementObject = Nothing
 136:          For Each objManagementObject As ManagementObject In objComputerSystem.GetRelated("Msvm_VirtualSystemSettingData")
 137:              objVirtualSystemsettingData = objManagementObject
 138:              For Each objResourceAllocationSettingData As ManagementObject In objVirtualSystemsettingData.GetRelated("Msvm_StorageAllocationSettingData")
 139:                  If objResourceAllocationSettingData("ResourceType") = 31 Then 'Logical Disk  http://msdn.microsoft.com/en-us/library/hh859775(v=vs.85).aspx
 140:                      objHardDisk = objResourceAllocationSettingData
 141:                      Dim strOldPath As String = objHardDisk("HostResource")(0)
 142:                      Dim strFileName As String = System.IO.Path.GetFileName(strOldPath)
 143:                      Dim strNewDiskPath As String = System.IO.Path.Combine(strDiskRootPath, strFileName)
 144:                      objHardDisk("HostResource") = New String(0) {strNewDiskPath} 'http://msdn.microsoft.com/en-us/library/cc136877(v=vs.85).aspx
 145:                      For Each objVirtualSystemManagementService As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_VirtualSystemManagementService")).Get
 146:                          Dim objParams As ManagementBaseObject = objVirtualSystemManagementService.GetMethodParameters("ModifyResourceSettings")
 147:                          Dim strResourceSettingData As String() = New String(0) {}
 148:                          strResourceSettingData(0) = objHardDisk.GetText(TextFormat.CimDtd20)
 149:                          objParams("ResourceSettings") = strResourceSettingData 'http://msdn.microsoft.com/en-us/library/hh850099(v=vs.85).aspx
 150:                          Dim objManagementBaseObject As ManagementBaseObject = objVirtualSystemManagementService.InvokeMethod("ModifyResourceSettings", objParams, Nothing)
 151:                          Call JobComplete(objManagementBaseObject, objManagementScope)
 152:                      Next
 153:                  End If
 154:              Next
 155:          Next
 156:          Return True
 157:      End Function
 158:   
 159:      Function RenameVM(ByVal objManagementScope As ManagementScope, ByVal strVMID As String, ByVal strVMName As String, ByVal strNewVMName As String) As Boolean
 160:          Dim objComputerSystem As ManagementObject = Nothing
 161:          For Each objManagementObject As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_ComputerSystem WHERE Name = '" & strVMID & "'")).Get
 162:              objComputerSystem = objManagementObject
 163:          Next
 164:   
 165:          Dim objVirtualSystemsettingData As ManagementObject = Nothing
 166:          For Each objManagementObject As ManagementObject In objComputerSystem.GetRelated("Msvm_VirtualSystemSettingData")
 167:              If String.Compare(objManagementObject("ElementName").ToString, strVMName, True) = 0 Then
 168:                  objVirtualSystemsettingData = objManagementObject
 169:                  objVirtualSystemsettingData("ElementName") = strNewVMName
 170:              End If
 171:          Next
 172:   
 173:          For Each objVirtualSystemManagementService As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_VirtualSystemManagementService")).Get
 174:              Dim objParams As ManagementBaseObject = objVirtualSystemManagementService.GetMethodParameters("ModifySystemSettings")
 175:              objParams("SystemSettings") = objVirtualSystemsettingData.GetText(TextFormat.CimDtd20)
 176:              Dim objManagementBaseObject As ManagementBaseObject = objVirtualSystemManagementService.InvokeMethod("ModifySystemSettings", objParams, Nothing)
 177:              Return JobComplete(objManagementBaseObject, objManagementScope)
 178:          Next
 179:      End Function
 180:   
 181:      Function JobComplete(ByVal objManagementBaseObject As ManagementBaseObject, ByVal objManagementScope As ManagementScope) As Boolean
 182:          'JobState New = 2  Starting = 3  Running = 4  Suspended = 5  ShuttingDown = 6  Completed = 7  Terminated = 8  Killed = 9  Exception = 10  Service = 11
 183:          If objManagementBaseObject("ReturnValue") <> 0 Then
 184:              Dim strJobPath As String = objManagementBaseObject("Job")
 185:              Dim objJob As New ManagementObject(objManagementScope, New ManagementPath(strJobPath), Nothing)
 186:              objJob.Get()
 187:              Do While objJob("JobState") = 3 Or objJob("JobState") = 4
 188:                  System.Threading.Thread.Sleep(1000)
 189:                  objJob.Get()
 190:              Loop
 191:              If objJob("JobState") <> 7 Then
 192:                  Console.WriteLine("ErrorCode=" & objJob("ErrorCode") & " JobState=" & objJob("JobState"))
 193:                  Return False
 194:              Else
 195:                  Return True
 196:              End If
 197:          Else
 198:              Return True
 199:          End If
 200:      End Function
 201:  End Module


今回のポイントとしては、インポート時に仮想ハードディスクのパスをきちんと指定することと、該当パスに仮想ハードディスクをきちんと配置しておくということになります。また、最新のHyper-Vではエクスポートは仮想マシンの稼働中でも可能となっている点も非常に便利な機能となっています。

いくつか複雑な手順がありましたが、Hyper-VマネージャーなのGUIでは設定しきれないポイントまで細かく指定できるのがやはりWMIの利点となります。

是非ご利用ください。





Hyper-Vをみんなで使いやすくするためのオープンコミュニティーをスタートしました

WMIのサンプルコードやTipなど幅広く情報共有してゆきたいと思います。

Hyper-Vというキーワードにピンときたら、是非メンバーとしてご参加ください。


→ 日本初のHyper-V オープンコミュニティー 「InvokeV」



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


次のページ

FC2Ad

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。