当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 将 Windows 磁盘与 VMWare VMDK 文件匹配

作者:精品下载站 日期:2024-12-14 20:13:39 浏览:14 分类:玩电脑

将 Windows 磁盘与 VMWare VMDK 文件匹配


当扩展VMWare虚拟机的磁盘大小或删除磁盘时,有时很难理解哪个VMware虚拟磁盘与特定的Windows VM磁盘匹配。如果磁盘较少且大小不同,则很容易找到所需的磁盘。但是,如果一个虚拟机创建了多个相同大小的VMDK(或RDM)磁盘或多个虚拟SCSI控制器怎么办?如何避免错误并选择 Windows 管理员要求您扩展(或缩小)的磁盘?

在本文中,我们将了解如何在 VMWare VM 上匹配 Windows 磁盘和虚拟磁盘 (VMDK)。

如何在Windows和VMWare中获取SCSI设备号?

打开磁盘管理控制台(

diskmgmt.msc

)在 Windows 中(在我们的示例中,它是 Windows Server 2016)。 SCSI 控制器名称和 SCSI 设备编号不会显示在磁盘列表中。要获取 SCSI 设备编号,请右键单击磁盘并选择属性。如您所见,VMWare 虚拟磁盘 SCSI 磁盘设备的设备端口信息显示在常规选项卡的位置字段中。

  • 位置 160=SCSI 总线控制器0

  • 目标 ID 1=设备 SCSI ID 为 1

将您看到的数据加入并获取 SCSI 磁盘地址:SCSI(0:1)。

[玩转系统] 将 Windows 磁盘与 VMWare VMDK 文件匹配

然后在 VMWare vSphere Client 中打开虚拟机属性。找到与您获得的 ID 具有相同虚拟设备节点号的磁盘。在我们的示例中,它是 SCSI(0:1) 硬盘 2。

[玩转系统] 将 Windows 磁盘与 VMWare VMDK 文件匹配

如果虚拟机上配置了多个具有不同 SCSI 控制器的虚拟磁盘(您最多可以向虚拟机添加 4 个 SCSI 控制器,每个控制器有 16 个磁盘),则手动查找 SCSI 设备编号是相当困难的。另请注意,Windows 和 VMWare 中的 SCSI 控制器编号可能不同。

如何使用 PowerShell 通过 UUID/序列号将 Windows 磁盘与 VMDK 匹配?

将 VMWare 虚拟磁盘映射到来宾 VM 内的磁盘的另一种方法是比较它们的唯一磁盘 ID。在 VMWare 中,此属性称为 UUID(唯一 ID),在 Windows 中称为序列号。让我们看看如何使用 PowerShell 获取虚拟磁盘的 UUID 和 SerialNumber。

默认情况下,所有VMWare虚拟机都有磁盘

EnableUUID=TRUE

参数启用。这意味着来宾操作系统必须查看虚拟磁盘 ID。

要获取有关 Windows 中磁盘的信息,您可以使用存储模块 cmdlet 或 WMI 查询。由于我们仍有一些运行 Windows Server 2008 R2 的虚拟机没有存储模块,因此我们将使用 WMI。

要获取 Windows 中的 SCSI 控制器编号、其上的 SCSI 设备编号、虚拟磁盘的序列号 (SerialNumber/UUID)、磁盘大小和磁盘编号,请运行以下 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 端口 0、SCSI 目标 0、串行 6000c2939b157427dadbace321ed4973

  • PHYSICALDRIVE1:SCSI 端口 0、SCSI 目标 1、串行 6000c2950ee961954909938642bb03b4

  • PHYSICALDRIVE1:SCSI 端口 4、SCSI 目标 10、串行 6000c2995fc3c4928d6650596bb02cef

[玩转系统] 将 Windows 磁盘与 VMWare 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)服务器并获取指定虚拟机的磁盘列表。结果必须包含 DataStore 名称、VMDK 文件路径、磁盘编号、磁盘大小和 UUID。

[玩转系统] 将 Windows 磁盘与 VMWare VMDK 文件匹配

然后,您可以通过 UUID 手动将在来宾 Windows 操作系统中看到的磁盘与 VMWare 虚拟磁盘进行匹配。

如果您在虚拟机的来宾操作系统中拥有管理员权限,则可以使用更方便的 PowerShell 脚本来匹配 Windows 磁盘和 VMWare VMDK 文件。该脚本通过网络连接来宾 Windows 操作系统,收集有关其本地磁盘的信息并将其与 VMWare VMDK 进行匹配。

以下是 PowerShell 脚本的完整代码:

Import-Module VMware.VimAutomation.Core -ErrorAction SilentlyContinue
connect-viserver ber-vmware1
$vmName = "ber-man01"
$WinHostName = "ber-mansrv01.a-d.site"
#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 磁盘与 VMWare VMDK 文件匹配

现在您可以轻松找到与给定虚拟 vmdk 磁盘匹配的 Windows 磁盘。

如果 Windows 中的虚拟磁盘通过装载点连接,则输出中不会有有关分配的驱动器号和卷标的信息。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯