QA@IT

コピーしたvhdのマウント時ドライブレター変更

4777 PV

ドライブレターを設定したvhdやvhdxファイルをコピーし、
片方のコピーだけのドライブレターをコマンドライン等のみで変える方法が
あれば教えてください。
仮想ディスクをバックアップとして用いるのですが、
両方のコピーを同時に別のドライブレターで自動的にマウントしたいという意図です。

・Gizmo Driveなどの、Windows非プリインストールソフトを使わない
・CUIかつバッチやpowershellなどで、手操作を伴わず自動でマウントできる
・マウントするファイル名により、その都度assign letterするのではなく、
 マウント時点で別のドライブレターであってほしい
という条件でお願いします。

○詳細

DISKPART> create vdisk file="d:\test_1.vhd" maximum=1024 type=expandable
(中略)
DISKPART> assign letter=s

としたあと

cmd> copy d:\test_1.vhd d:\test_2.vhd
を行い、

DISKPART> select vdisk file="d:\test_2.vhd"
(中略)
DISKPART> assign letter=x

とすると、test_1.vhdも次回マウント時にXドライブになってしまいます。
test_1.vhdはSドライブ、test_2.vhdはXドライブにしたいのです。

vhdの中をコピーせず、vhdファイル自体をコピーするのは、
vhdの中には100万ファイルで計300GB程度のデータがあり、
vhdファイル自体をコピーする方が圧倒的に早いためです。

ちなみにuniqueid disk id=で別々のGUIDにしてみましたが、だめでした。

よろしくお願いします。


flied_onionさんの回答を元に、検証して実現方法を
作成してみました。

諸事情によりGPTディスクにしているのですが、
あえて競合を起こしてから、online diskするのがミソのようです。
順番にマウントしてドライブレターを変えても、延々解消されませんでした。
UUIDを自分で変えてもそれは同じでした。

online disk前はドライブUUIDが同一で、
online disk後はドライブUUIDは勝手に違うようになっていました。

なんとなく想像ですが、diskpartで変更できるのはドライブのUUIDだけで、
ドライブレターの方はパーティションのUUIDが影響してるんではないかと…

以下、実現手順です。

rem # 1.バックアップ元chd作成 諸事情によりGPTで
create vdisk file="d:\test_1.vhd" maximum=200 type=expandable
attach vdisk
convert gpt
create partition primary
format fs=ntfs quick
rem # 2.バックアップ元ドライブレター設定
assign letter=s

rem # 3.ここまでいったらバックアップ元にしこしこファイルコピーする

rem # 4.コピーが終わったら一旦バックアップ元vhd取り外し
rem #   diskpartを終了してなければselectは不要
rem select vdisk file="d:\test_1.vhd"
detach vdisk

rem # 5.バックアップ先作成 バックアップ元データをコピー
create vdisk file="d:\test_2.vhd" source="d:\test_1.vhd" maximum=200 type=expandable

rem # 6.あえて競合させるために両方同時にマウントする
select vdisk file="d:\test_1.vhd"
attach vdisk
select vdisk file="d:\test_2.vhd"
attach vdisk

rem # 7.競合が出るので、強制的にONLINEする
online disk
rem # ドライブレターは勝手に空いてるとこが割り当てられる

rem # 8.バックアップ先ボリュームを選択
rem #   ボリューム番号はlist volumeで見る必要がある。ここでは仮に5
rem list volume
select volume 5

rem # 9.バックアップ先ドライブレター設定
rem #   勝手に割り振られたドライブレターは解除される
assign letter=x

rem # 10.バックアップ先マウント解除
detach vdisk

rem # 11.バックアップ元マウント解除
select vdisk file="d:\test_1.vhd"
detach vdisk

flied_onionさん、検証に結構お時間がかかったのではないでしょうか。
お手間をおかけしました。大変ありがとうございました。

あと、直接は関係ない事ですが、実際に作業したいvhd(100万ファイル370GB)では
DOS COPYよりdiakpart create vdisk source=のほうが1.5倍くらい
遅かったです…
さらに検証した結果、DOS COPYでも同じ手順で解決可能でしたので、
手順5は1回diskpartを抜けて、DOS COPYしたほうがいいみたいです。

回答

いろいろ試してみましたが、

  • create vdiskをsourceオプション付きで実行する (vhd uuidが変更されてコピーされる)
  • uniqueid disk id=でMBR uuidも変更する(しないと同時にマウントできない) の 2つでいけるかもしれません。 完全にうまくいくかは保証できませんが参考までに。

ただし

  • コピー(create vdisk ~ source)前に元のvhdをデタッチする必要がある
  • デタッチできない場合は、vhdをファイルコピーしてからコピー(create vdisk ~ source)すればできると思うが容量の問題は発生する。 という条件が付きます。

またMBR uuidはコピー毎に変えないといけませんので(※)、完全自動にするにはuuidを自動生成する方法を考えないといけません。
※ 常にオリジナルとコピーの2種類しか存在しないのであれば毎回同じMBR uuidにしても問題ないはずなのでこの問題は発生しない

簡単にしか確認してませんが、以下のような diskpart用のファイルで作成すると、
デタッチ後に再アタッチしても同じドライブレターでマウントされるようです。

rem # サンプルのため元ディスクを作る作業。既にあるので以下 4行は不要。
create vdisk file="r:\test_1.vhd" maximum=100 type=expandable
attach vdisk
create partition primary
assign letter=s
rem ## サンプルのためformatはトラブル回避のためにあえてしてません


rem # ここからがコピー
rem ## 元ディスクのデタッチ
rem ### ディスクを作成しない場合はデタッチのために元ディスクをselectする必要がある。
rem select vdisk file="r:\test_1.vhd"
detach vdisk

rem ## コピーする(vhd uuidが異なるディスクが作成できる)
create vdisk file="r:\test_2.vhd" source="r:\test_1.vhd" type=expandable

rem ### この時点ではまだMBR uuidが同一のため、ドライブレターが奪われないようにマウントしてしまう
select vdisk file="r:\test_1.vhd"
attach vdisk

rem ## コピーしたファイルをアタッチ
select vdisk file="r:\test_2.vhd"
attach vdisk

rem #### 余談:このタイミングでディスクの管理(GUI)を見ると競合エラーが出ているはず
rem ### MBR uuidを変更する。値は適宜変更する。GPTの場合は長さが違うので注意。
uniqueid disk id=4698AF35

rem ## 再アタッチしてドライブレターを設定
detach vdisk
attach vdisk
select partition 1
assign letter=x

このあと、2つの仮想ディスクをデタッチして、再アタッチしてみましたが、
とりあえずどちらからアタッチしても同じドライブレターでアタッチされました。

vhdのパス/ファイル名、uuidの値は適宜変更してください。
あと、パーティションが複数ある場合はボリュームの選択が難しいかもしれません。

編集 履歴 (1)
  • いただいた情報を元に、検証してみた結果
    目的通りのことができました。ありがとうございました。
    検証結果と実現コードは質問文に下に編集追加します。
    -
ウォッチ

この質問への回答やコメントをメールでお知らせします。