Matching Windows Disks to VMware VMDK Files

November 11, 2017 12 By Allan Kjaer

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

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.

The script ONLY works on VMDK files and virtual RDMs, and not on physical RDMs (the scripts fails if you are using physical RDMs on the VM).

Update 3 April 2002: with vSphere 7 and PowerCLI this is build in as a cmdlets, see here.

Please share this page if you find it usefull: