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

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:

7 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>

  2. Great script. Pretty complex to get all things puzzled together from different places.

    I wrote a disk resize script Windows/VMware. The only thing missing is that it associates a drive letter input directly with the right disk on the VM.

    1. Hi Enrico. Were you able to finish your resize script? I’m trying to implement a auto resize script on my Vmware but I’m still unable to find something that associates the drive letter to the correct VM HDD.

      1. No, have not found a method for the Windows drives that used as mount point.

        The script is also only for finde the correlation between VMDK and drive letters, I have not looked into, doing the resizing, with this script.

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.