Matching Windows Disks to VMware VMDK Files

I have been looking for this for at long time and there are some script on, VMware forums and other places, that can do this, but I was satisfied with them, since they did not give me all the information i needed.

So began to peace some of them tougher to a new one, And this one will return datastorename, path/filename, drive letters/volumename and other.

This script will connect på vCenter, find the VM, ask for creditials for the Windows server, at collect all the information and put in “$result”.

It first matches the VMDK file Unique ID (UUID) whit the Windows harddisk Serial, number, and finds the Windows disk deviceID. this is it then matches all the partitions, to find the drive letters and volume names.

## Modufy this sections as needed
#import-module -name vmwre.powercli
connect-viserver <vCenter name>
$vmName = "<VM Name>"
## modification below here not necessary to run  
$cred = if ($cred){$cred}else{Get-Credential}  
$win32DiskDrive  = Get-WmiObject -Class Win32_DiskDrive -ComputerName $vmName -Credential $cred
$vmHardDisks = Get-VM -Name $vmName | Get-HardDisk  
$vmDatacenterView = Get-VM -Name $vmName | Get-Datacenter | Get-View  
$virtualDiskManager = Get-View -Id VirtualDiskManager-virtualDiskManager 
$diskToDriveVolume = Get-WmiObject Win32_DiskDrive -ComputerName $vmName -Credential $cred| % {
  $disk = $_
  $partitions = "ASSOCIATORS OF " +
                "{Win32_DiskDrive.DeviceID='$($disk.DeviceID)'} " +
                "WHERE AssocClass = Win32_DiskDriveToDiskPartition"
  Get-WmiObject -Query $partitions -ComputerName $vmName -Credential $cred| % {
    $partition = $_
    $drives = "ASSOCIATORS OF " +
              "{Win32_DiskPartition.DeviceID='$($partition.DeviceID)'} " +
              "WHERE AssocClass = Win32_LogicalDiskToPartition"
    Get-WmiObject -Query $drives  -ComputerName $vmName -Credential $cred| % {
      New-Object -Type PSCustomObject -Property @{
        Disk        = $disk.DeviceID
        DriveLetter = $_.DeviceID
        VolumeName  = $_.VolumeName

      }
    }
  }
}
foreach ($disk in $win32DiskDrive)  
{  
  $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  
  }  
}  
$results = @()  
foreach ($vmHardDisk in $vmHardDisks)  
{  

  $vmHardDiskUuid = $virtualDiskManager.queryvirtualdiskuuid($vmHardDisk.Filename, $vmDatacenterView.MoRef) | foreach {$_.replace(' ','').replace('-','')}  
  $windowsDisk = $win32DiskDrive | where {$_.SerialNumber -eq $vmHardDiskUuid}  
  if (-not $windowsDisk){$windowsDisk = $win32DiskDrive | where {$_.AltSerialNumber -eq $vmHardDisk.ScsiCanonicalName.substring(12,24)}}  
  $result = "" | select vmName,vmHardDiskDatastore,vmHardDiskVmdk,vmHardDiskName,windowsDiskIndex,windowsDiskSerialNumber,vmHardDiskUuid,windowsDeviceID,drives,volumes  
  $result.vmName = $vmName.toupper()  
  $result.vmHardDiskDatastore = $vmHardDisk.filename.split(']')[0].split('[')[1]  
  $result.vmHardDiskVmdk = $vmHardDisk.filename.split(']')[1].trim()  
  $result.vmHardDiskName = $vmHardDisk.Name  
  $result.windowsDiskIndex = if ($windowsDisk){$windowsDisk.Index}else{"FAILED TO MATCH"}  
  $result.windowsDiskSerialNumber = if ($windowsDisk){$windowsDisk.SerialNumber}else{"FAILED TO MATCH"}  
  $result.vmHardDiskUuid = $vmHardDiskUuid  
  $result.windowsDeviceID = if ($windowsDisk){$windowsDisk.DeviceID}else{"FAILED TO MATCH"}  
  $driveVolumes = $diskToDriveVolume | where {$_.Disk -eq $windowsDisk.DeviceID}
  $result.drives = $driveVolumes.DriveLetter
  $result.volumes = $driveVolumes.VolumeName
  $results += $result
}  
$results = $results | sort {[int]$_.vmHardDiskName.split(' ')[2]}  
$results | ft -AutoSize  

The output looks like this

vmName      vmHardDiskDatastore vmHardDiskVmdk           vmHardDiskName windowsDiskIndex windowsDiskSerialNumber          vmHardDiskUuid                   windowsDeviceID    drives   volumes
------      ------------------- --------------          -------------- ---------------- -----------------------          --------------                   ---------------    ------   -------
test-vm     FC01                 test-vm/test-vm.vmdk       Hard disk 1                   0 6000c29c481f32e9763fe6d2d8dc8f7b 6000C29c481f32e9763fe6d2d8dc8f7b \\.\PHYSICALDRIVE0 C:
test-vm     FC01                 test-vm/test-vm_1.vmdk     Hard disk 2                   1 6000c297d1a7352ed5ee1b870023f57d 6000C297d1a7352ed5ee1b870023f57d \\.\PHYSICALDRIVE1 D:       Data
test-vm     FC03                 test-vm/test-vm.vmdk       Hard disk 3                   2 6000c290e36c2f3b641a56308551e998 6000C290e36c2f3b641a56308551e998 \\.\PHYSICALDRIVE2 {E:, F:} {New Volume, New Volume}

I have not tested this in all scenarios, so do your own testing before using this scripts.

Using this script and method is at your own risk

Notes.

The script does not always works if using mount points i windows.

Share This:

4 thoughts on “Matching Windows Disks to VMware VMDK Files

  1. Can you please help. I am getting following error when trying to fetch details from WINDOWS platform system, post providing correct credential

    PowerCLI E:\> .\dskmpCh1.ps1

    Name Port User
    —- —- —-
    c1srv2vvc01 443 BALICIN\Drmadmvc

    cmdlet Get-Credential at command pipeline position 1
    Supply values for the following parameters:
    Credential
    Get-WmiObject : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
    At E:\dskmpCh1.ps1:7 char:20
    + $win32DiskDrive = Get-WmiObject -Class Win32_DiskDrive -ComputerName $vmName -C …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [Get-WmiObject], UnauthorizedAccessException
    + FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

    Get-WmiObject : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
    At E:\dskmpCh1.ps1:11 char:22
    + $diskToDriveVolume = Get-WmiObject Win32_DiskDrive -ComputerName $vmName -Creden …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [Get-WmiObject], UnauthorizedAccessException
    + FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

    Exception calling “QueryVirtualDiskUuid” with “2” argument(s): “The object has already been deleted or has not been completely created”
    At E:\dskmpCh1.ps1:45 char:3
    + $vmHardDiskUuid = $virtualDiskManager.queryvirtualdiskuuid($vmHardDisk.Filenam …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : VimException

    You cannot call a method on a null-valued expression.
    At E:\dskmpCh1.ps1:47 char:66
    + if (-not $windowsDisk){$windowsDisk = $win32DiskDrive | where {$_.AltSerialNum …
    + ~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

    Exception calling “QueryVirtualDiskUuid” with “2” argument(s): “The object has already been deleted or has not been completely created”
    At E:\dskmpCh1.ps1:45 char:3
    + $vmHardDiskUuid = $virtualDiskManager.queryvirtualdiskuuid($vmHardDisk.Filenam …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : VimException

    You cannot call a method on a null-valued expression.
    At E:\dskmpCh1.ps1:47 char:66
    + if (-not $windowsDisk){$windowsDisk = $win32DiskDrive | where {$_.AltSerialNum …
    + ~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

    vmName vmHardDiskDatastore vmHardDiskVmdk vmHardDiskName windowsDiskIndex windowsDiskSerialNumber vmHardDiskUuid windowsDeviceID drives volumes
    —— ——————- ————– ————– —————- ———————– ————– ————— —— ——-
    C5SRW2TST01 HP_SSD_Win11 C5SRW2TST01/C5SRW2TST01.vmdk Hard disk 1 FAILED TO MATCH FAILED TO MATCH FAILED TO MATCH
    C5SRW2TST01 HP_SSD_Win11 C5SRW2TST01/C5SRW2TST01_1.vmdk Hard disk 2 FAILED TO MATCH FAILED TO MATCH FAILED TO MATCH

    PowerCLI E:\cajetan\cajetan123>

Leave a Reply

Your e-mail address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.