Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> ระบบ >> Windows Server

จับคู่ดิสก์ Windows กับไฟล์ VMDK ของ VMware

เมื่อต้องการขยายขนาดดิสก์ของเครื่องเสมือน VMware หรือลบดิสก์ บางครั้งจะยากที่จะทราบว่า VMDK ใดตรงกับดิสก์ Windows VM ใด หากมีดิสก์เพียงไม่กี่ตัวและขนาดต่างกัน จะหาได้ง่าย แต่ถ้ามี VMDK (หรือ RDM) หลายตัวที่มีขนาดเท่ากัน หรือมีคอนโทรลเลอร์ SCSI เสมือนหลายตัว จะหลีกเลี่ยงข้อผิดพลาดและเลือกดิสก์ที่ผู้ดูแล Windows ขอให้ขยาย (หรือย่อ) ได้อย่างไร

วิธีดูหมายเลขอุปกรณ์ SCSI ใน Windows และ VMware

เปิดคอนโซลการจัดการดิสก์ (diskmgmt.msc) ใน Windows (ตัวอย่างใช้ Windows Server 2016) ชื่อคอนโทรลเลอร์ SCSI และหมายเลขอุปกรณ์ SCSI ไม่แสดงในรายการดิสก์ เพื่อดูหมายเลขอุปกรณ์ SCSI ให้คลิกขวาที่ดิสก์แล้วเลือก Properties ข้อมูลพอร์ตอุปกรณ์สำหรับ VMware Virtual disk SCSI Disk Device จะแสดงในฟิลด์ Location แท็บ General

  • Location 160 = SCSI Bus Controller 0
  • Target ID 1 = SCSI ID ของอุปกรณ์คือ 1

นำข้อมูลมารวมกันจะได้ที่อยู่ดิสก์ SCSI: SCSI(0:1)

จับคู่ดิสก์ Windows กับไฟล์ VMDK ของ VMware

จากนั้นเปิดคุณสมบัติเครื่องเสมือนใน VMware vSphere Client หาดิสก์ที่มีหมายเลข Virtual Device Node เท่ากับ ID ที่ได้มา ในตัวอย่างคือ SCSI(0:1) Hard Disk 2

จับคู่ดิสก์ Windows กับไฟล์ VMDK ของ VMware

หากตั้งค่าดิสก์เสมือนหลายตัวกับคอนโทรลเลอร์ SCSI ต่างกัน (เพิ่มได้สูงสุด 4 คอนโทรลเลอร์ SCSI ตัวละ 16 ดิสก์) การหาหมายเลขอุปกรณ์ SCSI แบบมืออาจยุ่งยาก โปรดทราบว่าหมายเลขคอนโทรลเลอร์ SCSI ใน Windows และ VMware อาจต่างกัน

จับคู่ดิสก์ Windows กับ VMDK ด้วย UUID/Serial Number ผ่าน PowerShell

อีกวิธีหนึ่งคือเปรียบเทียบ ID ดิสก์ที่ไม่ซ้ำกัน ใน VMware เรียกว่า UUID (Unique ID) ส่วน Windows เรียกว่า Serial Number มาดูวิธีดึง UUID และ SerialNumber ของดิสก์เสมือนด้วย PowerShell

โดยค่าเริ่มต้น VM ทุกตัวของ VMware จะมีพารามิเตอร์ EnableUUID=TRUE เปิดอยู่ หมายความว่า Guest OS ต้องเห็น ID ดิสก์เสมือน

เพื่อดูข้อมูลดิสก์ใน Windows สามารถใช้คอมมานด์เลตโมดูล Storage หรือคิวรี WMI เนื่องจากยังมี VM ที่รัน Windows Server 2008 R2 ซึ่งไม่มีโมดูล Storage จึงใช้ WMI

รันคำสั่ง PowerShell นี้เพื่อดูหมายเลขคอนโทรลเลอร์ SCSI หมายเลขอุปกรณ์ SCSI Serial Number ของดิสก์เสมือน (SerialNumber/UUID) ขนาดดิสก์ และหมายเลขดิสก์ใน Windows:

$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 Port 0, SCSI Target 0, Serial 6000c2939b157427dadbace321ed4973
  • PHYSICALDRIVE1: SCSI Port 0, SCSI Target 1, Serial 6000c2950ee961954909938642bb03b4
  • PHYSICALDRIVE2: SCSI Port 4, SCSI Target 10, Serial 6000c2995fc3c4928d6650596bb02cef

จับคู่ดิสก์ Windows กับไฟล์ VMDK ของ VMware

ต่อมา ลองดูหมายเลขคอนโทรลเลอร์ SCSI และ UUID ของดิสก์ที่ระบุในการตั้งค่า VMware 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 ที่ระบุ ผลลัพธ์จะมีชื่อ DataStore, พาธไฟล์ VMDK, หมายเลขดิสก์, ขนาดดิสก์ และ UUID

จับคู่ดิสก์ Windows กับไฟล์ VMDK ของ VMware

จากนั้นสามารถจับคู่ดิสก์ใน Guest Windows OS กับดิสก์เสมือน VMware ด้วย UUID ได้ด้วยตนเอง

หากมีสิทธิ์ผู้ดูแลใน Guest OS ของ VM สามารถจับคู่ดิสก์ Windows และไฟล์ VMDK ของ VMware ด้วยสคริปต์ PowerShell ที่สะดวกกว่า สคริปต์จะเชื่อมต่อ Guest Windows OS ผ่านเครือข่าย รวบรวมข้อมูลดิสก์ท้องถิ่น และจับคู่กับ VMDK ของ VMware

โค้ดเต็มของสคริปต์ 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

จับคู่ดิสก์ Windows กับไฟล์ VMDK ของ VMware

ตอนนี้คุณสามารถหาได้ง่ายว่าดิสก์ Windows ใดตรงกับ VMDK เสมือนที่ระบุ

หากดิสก์เสมือนใน Windows เชื่อมต่อผ่าน mount point จะไม่มีข้อมูลตัวอักษรไดรฟ์และป้ายกำกับโวล्यูมในผลลัพธ์