При увеличении размера или удалении диска в VMWare для виртуальных машин с Windows, иногда сложно понять какой VMware virtual disk соответствует определенном диску в Windows ВМ. Если дисков не много и все они отличаются по размеру, найти нужный диск просто. Но что делать, если для ВМ создано несколько VMDK (или RDM) дисков одинакового размера, или для ВМ создано несколько виртуальных SCSI контроллеров? Как не ошибиться и выбрать именно тот диск, который требует расширить (или уменьшить) администратор Windows.
В этой статье мы рассмотрим, как сопоставить диски Windows с виртуальными дисками (VMDK) на ВМ VMWare.
Проверяем номер SCSI устройства в Windows и VMWare
Откройте консоль управления дисками Disk Manager (diskmgmt.msc) в Windows (в нашем примере это Windows Server 2016). В списке дисков не отображается имя SCSI контроллера и номер SCSI устройства на нем. Чтобы определить номер SCSI устройства, щелкните по диску и выберите Properties. Как вы видите, на вкладке General в поле Location указано информация о порте устройства VMWare Virtual disk SCSI Disk Device.
- Location 160 = SCSI Bus Controller 0
- Target ID 1 = номер SCSI ID устройства 1
Объединяем полученные данные и получаем адрес диска SCSI(0:1).
Теперь откройте свойства виртуальной машины VMWare в vSphere Client. Найдите диск, у которого Virtual Device Node соответствует полученному ID. В нашем примере это SCSI(0:1) Hard Disk 2.
Если в виртуальной машине настроено множество виртуальных дисков с разными SCSI контроллерами (вы можете добавить в ВМ до 4 SCSI контроллеров по 16 дисков в каждом), найти номер SCSI устройства вручную довольно сложно. Кроме того, имейте в виду, что номера SCSI контроллеров в Windows и VMWare могут отличаться.
Как сопоставить диски Windows с VMDK файлами по UUID/SerialNumber через PowerShell?
Другой способ сопоставления виртуальных дисков VMWare с дисками внутри гостевой ВМ – сравнить их по уникальному идентификатору диска. Со стороны VMWare этот атрибут называется UUID (Unique ID), а в Windows – Serial Number. Рассмотрим, как получить значения UUID и SerialNumber виртуальных дисков через PowerShell.
disk.EnableUUID=TRUE
, это означает, что гостевая ОС должна видеть идентификаторы виртуальных дисков.Для получения информации о дисках в Windows вы можете использовать командлеты модуля Storage, или WMI запросы. Т.к. в нашем случае ещё остались ВМ с Windows Server 2008 R2, в которых отсутствует модуль Storage, мы будем использовать WMI.
Чтобы получить номер SCSI контроллера, номер SCSI устройства на нем, серийный номер виртуального диска (SerialNumber/UUID), размер и номер диска в 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 видит три диска:
- PHYSICALDRIVE0: SCSI Port 0, SCSI Target 0, Serial 6000c2939b153417dedbdce371ed497b
- PHYSICALDRIVE1: SCSI Port 0, SCSI Target 1, Serial 6000c2950ee961954909259642bb03bf
- PHYSICALDRIVE1: SCSI Port 4, SCSI Target 10, Serial 6000c2995fc3c4728de8b0596bb02ce3
Теперь попробуем получить номера SCSI контроллеров и UUID дисков, которые указаны в настройках виртуальной машины VMware. Для получения параметров ВМ нужно воспользоваться PowerCLI.
Import-Module VMware.VimAutomation.Core -ErrorAction SilentlyContinue connect-viserver vcenter1 $vmName="msk-sql1" $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) и для указанной ВМ получит список дисков. После выполнения скрипта вы получите список виртуальных дисков для ВМ. Результат должен содержать имя DataStore, путь к vmdk файлу, номера диска, его размер и UUID.
Теперь по полученным UUID вы можете вручную сопоставить диски, которые видны в гостевой Windows с виртуальными дисками VMWare.
Если у вас есть права администратора в виртуальной машине, для которой нужно сопоставить диски Windows и vmdk файлы в VMWare, можно воспользоваться более простым в использовании PowerShell скриптом. Скрипт обращается к гостевой Windows по сети, собирает информацию о локальных дисках и показывает соответствие с дисками VMWare.
Полный код PowerShell скрипта:
Import-Module VMware.VimAutomation.Core -ErrorAction SilentlyContinue connect-viserver vcenter1 $vmName = "msk-sql1" $WinHostName = "msk-sqlclu1.winitpro.ru" #Получить список дисков виртуальной машины VMWare $vmDisks = Get-VM -Name $vmName | Get-HardDisk $vmDatacenterView = Get-VM -Name $vmName | Get-Datacenter | Get-View $virtualDiskManager = Get-View -Id VirtualDiskManager-virtualDiskManager # Учетная запись и пароль администартора для доступа к гостевой ОС $cred = if ($cred){$cred}else{Get-Credential} # Получить список дисков и разделов Windows через 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 } } } } #получить серийный номер диска 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 } } #Перебор всех дисков ВМ, сопоставление с дисками Windows по 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.
Теперь вы можете без проблем разобраться какому виртуальному диску соответствует диск в Windows.