Windows Server
 Computer >> コンピューター >  >> システム >> Windows Server

【VMware】WindowsディスクとVMDK仮想ディスクを正確に照合する方法

VMware仮想マシンのディスクサイズを拡張したり、不要になったディスクを削除したりする際、「特定のWindowsゲストOS内のディスクがどのVMware仮想ディスクに該当するのか」の判別に悩むことがあります。ディスク数が少なく容量も異なっていれば容易に見分けられますが、同一サイズのVMDK(またはRDM)ディスクが複数存在したり、仮想SCSIコントローラーが複数構成されていたりする場合はどうすればよいでしょうか。Windows管理者から「このディスクを拡張してほしい」と依頼された際に、誤ったディスクを選択しないための実践的な照合方法を解説します。

WindowsとVMwareでSCSIデバイス番号を確認する方法

まず、Windows(本記事の例ではWindows Server 2016)でディスクの管理コンソール(diskmgmt.msc)を開きます。ただし、ディスク一覧にはSCSIコントローラー名やSCSIデバイス番号は表示されません。SCSIデバイス番号を確認するには、対象のディスクを右クリックしてプロパティを選択します。全般タブの場所フィールドに、VMware Virtual disk SCSI Disk Deviceのデバイスポート情報が表示されます。

  • 場所 160 = SCSIバスコントローラー 0
  • ターゲットID 1 = デバイスのSCSI IDは1

これらの情報を組み合わせると、SCSIディスクアドレスはSCSI(0:1)であることがわかります。

【VMware】WindowsディスクとVMDK仮想ディスクを正確に照合する方法

次に、VMware vSphere Clientで仮想マシンの設定を開きます。先ほど取得したIDと同じVirtual Device Node番号を持つディスクを探してください。この例ではSCSI(0:1)のHard Disk 2が該当します。

【VMware】WindowsディスクとVMDK仮想ディスクを正確に照合する方法

仮想マシンに複数の異なるSCSIコントローラーを持つ仮想ディスクが構成されている場合(1台の仮想マシンには最大4つのSCSIコントローラーを追加でき、各コントローラーに16台までディスクを接続可能)、手動でSCSIデバイス番号を突き合わせるのはかなり煩雑です。さらに、WindowsとVMwareではSCSIコントローラーの番号が一致しないケースがある点にも注意が必要です。

PowerShellでUUID/シリアル番号を使ってWindowsディスクとVMDKを照合する方法

もう一つの確実な方法として、ディスク固有のIDを比較することで、VMware仮想ディスクとゲストOS内のディスクをマッピングできます。VMwareではこの属性はUUID(Unique ID)、WindowsではSerialNumber(シリアル番号)と呼ばれます。ここではPowerShellを使って仮想ディスクのUUIDとシリアル番号を取得する手順を紹介します。

デフォルトでは、すべてのVMware仮想マシンでディスクのEnableUUID=TRUEパラメーターが有効になっています。これは、ゲストOSが仮想ディスクのIDを認識できることを意味します。

Windowsのディスク情報を取得するには、StorageモジュールのコマンドレットまたはWMIクエリを利用できます。今回はStorageモジュールが搭載されていないWindows Server 2008 R2のVMもまだ稼働している環境を想定し、WMIを使用します。

SCSIコントローラー番号、その上のSCSIデバイス番号、仮想ディスクのシリアル番号、ディスクサイズ、Windows上のディスク番号をまとめて取得するには、次のPowerShellコマンドを実行します。

$DiskInfo = foreach ($disk in Get-WmiObject Win32_DiskDrive) {
    [pscustomobject]@{
    "DeviceID"=$disk.DeviceID;
    "Caption"=$disk.Caption;
    "Capacity (GB)"=[math]::Round($disk.size / 1GB,0);  
    "SerialNumber" =$disk.SerialNumber
    "SCSIControllerNum"=$disk.scsiport;
    "SCSIDeviceNum"=$disk.scsitargetid;   
    }
}
$DiskInfo|ft

この例では、Windowsは3つのディスクを認識しています。

  • PHYSICALDRIVE0:SCSIポート0、SCSIターゲット0、シリアル 6000c2939b157427dadbace321ed4973
  • PHYSICALDRIVE1:SCSIポート0、SCSIターゲット1、シリアル 6000c2950ee961954909938642bb03b4
  • PHYSICALDRIVE1:SCSIポート4、SCSIターゲット10、シリアル 6000c2995fc3c4928d6650596bb02cef

【VMware】WindowsディスクとVMDK仮想ディスクを正確に照合する方法

続いて、VMware仮想マシンの設定で定義されているディスクのSCSIコントローラー番号とUUIDを取得しましょう。VM設定を確認するには、PowerCLIコンソールを使用します。

Import-Module VMware.VimAutomation.Core -ErrorAction SilentlyContinue
connect-viserver ber-vmware1 

$vmName="ber-man01"
$vmHardDisks = Get-VM -Name $vmName | Get-HardDisk 
$vmDatacenterView = Get-VM -Name $vmName | Get-Datacenter | Get-View 
$virtualDiskManager = Get-View -Id VirtualDiskManager-virtualDiskManager 

$vmresults = @()  
foreach ($vmHardDisk in $vmHardDisks)  
{  
  $string = $vmHardDisk.Filename
  $vmHardDiskUuid = ($vmHardDisk.ExtensionData.Backing.Uuid | ForEach-Object {$_.replace(' ','').replace('-','')})
  $vmresult = "" | Select-Object vmHardDiskDatastore,vmHardDiskVmdk,vmHardDiskName,vmHardDiskSize,vmHardDiskUuid
  $vmresult.vmHardDiskDatastore = $vmHardDisk.filename.split(']')[0].split('[')[1]  
  $vmresult.vmHardDiskVmdk = $vmHardDisk.filename.split(']')[1].trim()  
  $vmresult.vmHardDiskName = $vmHardDisk.Name
  $vmresult.vmHardDiskSize = $vmHardDisk.CapacityGB
  $vmresult.vmHardDiskUuid = $vmHardDiskUuid    
  $vmresults += $vmresult  
}
$vmresults | ft 

このスクリプトはvCenter(またはESXi)サーバーに接続し、指定したVMのディスク一覧を取得します。結果にはデータストア名、VMDKファイルパス、ディスク番号、ディスクサイズ、UUIDが含まれます。

【VMware】WindowsディスクとVMDK仮想ディスクを正確に照合する方法

あとは、ゲストWindows OSで確認したディスクとVMware仮想ディスクをUUIDをもとに手動で照合できます。

VMのゲストOSに対する管理者権限を持っている場合は、より便利なPowerShellスクリプトによってWindowsディスクとVMware VMDKファイルを自動照合できます。このスクリプトはネットワーク経由でゲストWindows OSに接続し、ローカルディスクの情報を収集したうえでVMware VMDKと突き合わせを行います。

以下がPowerShellスクリプトの全文です。

Import-Module VMware.VimAutomation.Core -ErrorAction SilentlyContinue
connect-viserver ber-vmware1
$vmName = "ber-man01"
$WinHostName = "ber-mansrv01.woshub.com"
#Get the list of disks of a VMWare virtual machine
$vmDisks = Get-VM -Name $vmName | Get-HardDisk 
$vmDatacenterView = Get-VM -Name $vmName | Get-Datacenter | Get-View 
$virtualDiskManager = Get-View -Id VirtualDiskManager-virtualDiskManager 
# Enter the administrator credentials to access the guest Windows
$cred = if ($cred){$cred}else{Get-Credential}  
# Getting the list of Windows disks and partitions using WMI
$winDisk  = Get-WmiObject -Class Win32_DiskDrive -ComputerName $WinHostName -Credential $cred
$diskToDriveVolume = Get-WmiObject Win32_DiskDrive -ComputerName $WinHostName -Credential $cred| % {
  $disk = $_
  $partitions = "ASSOCIATORS OF " +
                "{Win32_DiskDrive.DeviceID='$($disk.DeviceID)'} " +
                "WHERE AssocClass = Win32_DiskDriveToDiskPartition"
  Get-WmiObject -Query $partitions -ComputerName $WinHostName -Credential $cred| % {
    $partition = $_
    $drives = "ASSOCIATORS OF " +
              "{Win32_DiskPartition.DeviceID='$($partition.DeviceID)'} " +
              "WHERE AssocClass = Win32_LogicalDiskToPartition"
    Get-WmiObject -Query $drives  -ComputerName $WinHostName -Credential $cred| % {
      New-Object -Type PSCustomObject -Property @{
        Disk        = $disk.DeviceID
        DriveLetter = $_.DeviceID
        VolumeName  = $_.VolumeName
       }
    }
  }
}
 #Getting a disk serial number 
foreach ($disk in $winDisk)  
{  
  $disk | Add-Member -MemberType NoteProperty -Name AltSerialNumber -Value $null 
  $diskSerialNumber = $disk.SerialNumber  
  if ($disk.Model -notmatch 'VMware Virtual disk SCSI Disk Device')  
  {  
    if ($diskSerialNumber -match '^\S{12}$'){$diskSerialNumber = ($diskSerialNumber | foreach {[byte[]]$bytes = $_.ToCharArray(); $bytes | foreach {$_.ToString('x2')} }  ) -join ''}  
    $disk.AltSerialNumber = $diskSerialNumber 
  }  
}  
#Searching all VM disks and matching them with Windows disks by their SerialNumber / UUID
$diskMaps = @()  
foreach ($vmDisk in $vmDisks)  
{  
  $vmDiskUuid = $virtualDiskManager.queryvirtualdiskuuid($vmDisk.Filename, $vmDatacenterView.MoRef) | foreach {$_.replace(' ','').replace('-','')}  
  $windowsDisk = $winDisk | where {$_.SerialNumber -eq $vmDiskUuid}  
  if (-not $windowsDisk){$windowsDisk = $winDisk | where {$_.AltSerialNumber -eq $vmDisk.ScsiCanonicalName.substring(12,24)}}  
  $curDiskMap = "" | select  vmDiskDatastore, vmDiskVmdk, vmDiskName, windowsDiskIndex,  vmDiskUuid, windowsDeviceID, drives, volumes  
  $curDiskMap.vmDiskDatastore = $vmDisk.filename.split(']')[0].split('[')[1]  
  $curDiskMap.vmDiskVmdk = $vmDisk.filename.split(']')[1].trim()  
  $curDiskMap.vmDiskName = $vmDisk.Name  
  $curDiskMap.windowsDiskIndex = if ($windowsDisk){$windowsDisk.Index}else{"FAILED TO MATCH"}  
  $curDiskMap.vmDiskUuid = $vmDiskUuid  
  $curDiskMap.windowsDeviceID = if ($windowsDisk){$windowsDisk.DeviceID}else{"FAILED TO MATCH"}  
  $driveVolumes = $diskToDriveVolume | where {$_.Disk -eq $windowsDisk.DeviceID}
  $curDiskMap.drives = $driveVolumes.DriveLetter
  $curDiskMap.volumes = $driveVolumes.VolumeName
  $diskMaps += $curDiskMap
}  
$diskMaps = $diskMaps | sort {[int]$_.vmDiskName.split(' ')[2]}  
$diskMaps | ft

このスクリプトは、Windows側のドライブレターやボリュームラベルの情報も併せて返してくれます。

【VMware】WindowsディスクとVMDK仮想ディスクを正確に照合する方法

これにより、どのWindowsディスクがどの仮想vmdkディスクに対応しているのかを一目で把握できるようになります。

なお、Windows上で仮想ディスクがマウントポイント経由で接続されている場合は、出力結果にドライブレターやボリュームラベルの情報は表示されない点にご注意ください。

  1. Windows PCで重複ファイルを簡単に見つけて削除する方法

    Windowsパソコンにおいて、重複ファイルは昔からの悩みの種です。不要なストレージ容量を占有し、ファイル整理の妨げになるだけでなく、大切な思い出の写真を振り返っているときに同じ画像が何度も表示されると、せっかくの感動も台無しになってしまいます。一方で、元のファイルが意図せず変更されていないか確認するために、あえて重複ファイルと比較したいケースもあります。この記事では、「Disk Analyzer Pro」を使って、PC内の完全に一致する重複ファイルを見つける方法をわかりやすく解説します。 Windows PCで重複ファイルを見つける手順 ステップ1: Microsoft Storeから、

  2. VirtualBoxのVDIをVMwareのVMDKに変換する3つの方法【VBoxManage・QEMU対応】

    VirtualBoxとVMware製品の両方を使っている仮想化ユーザーなら、仮想ディスクの形式変換はぜひ覚えておきたいテクニックです。変換が必要になる理由はさまざまで、ライセンスやマシンの状態を維持したい場合、互換性テストのために別のソフトウェアで動作させたい場合など、仮想化愛好家ならではのニーズが挙げられます。 本記事では、VirtualBoxが使用する「.vdi」形式からVMwareが使用する「.vmdk」形式へ(そしてその逆方向へ)、仮想ハードディスクを変換する確実な2つの方法と、状況次第で使える可能性のある第3の方法を紹介します。さらに、VHDやRAWなど、その他のフォーマットへの変換