The idea of this article and a script described came to me couple of days ago after one of the readers commented on my article about VMware virtual disks and Windows drive volumes. The question was: is there any way to match physical drives to volume labels in Windows with PowerShell.

Alex Chaika

Alex Chaika is a Microsoft Certified Solution Expert (MCSE) with more than 15 years of experience in IT systems engineering. He currently focuses on PowerShell and VMware PowerCLI.

I knew that there is no straightforward way to do that, because Windows stores information about physical disks and their controllers in one object, relationship information between physical disks and partitions in another, and information about logical disks and partitions in a third.

Thus, we have to combine the different information sources to get the appropriate result.

The get-match function is an important part of the script. It matches the VMware hard disks to the Windows physical drives. I already explained how this part works in my previous article. Thus, I will only discuss the new code below.

Here, I’m saving the results of the get-match function into the $WinDevIDs variable. The screenshot below displays the contents of the variable.

Get match function results

Get match function results

Now I need to get the partitions and then the volume labels for those physical drives:

In order to do that I need to get information about physical disk to partition mappings from the Win32_DiskDriveToPartition WMI object and to store this data in the $DiskDrivesToDiskPartition variable. This information comes in a pretty raw format, as you can see below:

Win32_DiskDriveToPartition WMI object

Win32_DiskDriveToPartition WMI object

The only valuable pieces of information for me are the disk and partition numbers and physical drive numbers, because we can use these numbers to determine the relationship between the physical disks and the partitions that reside on them.

The “foreach” loop above goes through every physical drive in the $WinDevIDs variable and compares the physical drive number to information extracted from the __RELPATH field of the Win32_DiskDriveToDiskPartition object. If a match is found, the whole __RELPATH field goes into the $PreRes variable.

In order to find the disk and partition numbers which correspond to the current physical drive number, I use a for loop, going through each record in the $PreRes variable comparing it to a regex expression to find the relevant records.

Then I store the physical drive number, and disk/partition information, which I extract from service variable $matches, to the fields of the $WinDev hash table. At the end, all information is stored into the $WinDevsToDrives variable. The contents of $WinDevsToDrives then looks like this:

Contents of WinDevsToDrives

Contents of WinDevsToDrives

After I’ve figured out which partitions reside on the particular physical drives, comes the final part: matching this information to volume labels. To do that, I’m firstly getting the information about the relationship between logical drives and partitions from the Win32_LogicalDiskToPartition object. Below you see the properties of the object:

Win32_LogicalDiskToPartition object

Win32_LogicalDiskToPartition object

Next, I create the $final hash table. Then I loop through every record in the $WinDevsToDrives variable, which I’ve got on the previous step, and fill it with the contents of the $WinDevVol.PhysicalDrive and the $WinDevVol.DiskAndPart fields, together with the corresponding information from the $WinDevsToDrives variable.

In the next step I’m comparing the disk and partition information stored in the DiskAndPart field of the $WinDevsToDrives variable to the data I’ve got from the __RELPATH field of the Win32_LogicalDiskToPartition object. If a match is found, I’m using regex to extract the logical disk label from this data, and saving it to the $WinDevVol.VolumeLabel hash table field using the  service variable $matches. Finally, I put all the information into the $final hash table and export this hash table to a .csv file. Below you can see screenshots from two .csv files this script generated. One displays the known matches between VMware disks and Windows drives, and another one the matches between Windows drives and volumes:

VMware disks to Windows drives matches

VMware disks to Windows drives matches

Windows drives to volumes matches

Windows drives to volumes matches

Join the 4sysops PowerShell group!

Your question was not answered? Ask in the forum!


Users who have LIKED this post:

  • avatar
  1. Albert 3 years ago


    Thank you for sharing the wonderful script.
    Would it be possibleto combine the .CSV result into just one file rahter than two separate files ?


    • Author
      Alex Chaika 3 years ago

      I'd say it is rather inconvenient than impossible. As you can see there could be several partitions on the same physical drive, so placing all this information into the same cvs file could be confusing.


      Users who have LIKED this comment:

      • avatar
  2. Sebastian 2 years ago

    Is it possible to extend it that the script additionally reports the partitions "description"?

    E.g. "C:" = Partition label and "System" is the partitions description, as seen in the disk management.

    I would need that because I have to work with many servers which use "mount points" instead of partition labels aka. drive letters. In those cases your current script reports empty partition labels.. If I had the partition description, I could easily match with my VHDs.



  3. gas the kikes 2 years ago

    This script is woefully incomplete and assumes things like the disk controllers are SCSI rather than NVMe and that the VM's names are the same as the computers hostname


Leave a reply

Your email address will not be published. Required fields are marked *


© 4sysops 2006 - 2019


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account