PowerCLI and VVols Part IV: Correlating a Windows NTFS to a VMDK

My last post in this series was about getting a VVol UUID and figuring out what volume on a FlashArray it is. But what about the step before that? If I have a guest OS file system how do I even figure out what VMDK it is?

There is a basic option, which can potentially be used, which is correlating the bus ID and the unit ID of the device in the guest and matching it to what VMware displays for the virtual disks.

But that always felt to me as somewhat inexact.  What if you accidentally look at the wrong VM object and then do something to a volume you do not mean to? Or the opposite?

Not ideal. Luckily there is a more exact approach. I will focus this particular post on Windows. I will look at Linux in an upcoming one.

First off, well if this is VVols, wont the volume in Windows just show me my FlashArray (or whatever vendor/model) volume serial number?

No–this is the same idea as with VMFS-based (or NFS, or VSAN-based) virtual disks. VMware virtualizes the VPD information of the volume so you can Storage vMotion it (etc.) between different storage without the guest thinking it sees different storage.

If we look at my Windows VM (which currently has one disk) we will see that the following is its serial number:

NOTE: get-disk only works on Windows 2012 and later, you have to use WMI for earlier versions…

If this field is blank, you likely have the VM advanced setting disk.EnableUUID set to false or unset. This needs to be set to either TRUE.

This setting is the key for this to work. Here is a VMware KB that talks about it:

https://kb.vmware.com/s/article/50121797

Is there a down side to setting this? Well I am still looking into it, but the main thing I know is that if this is set on a VM and that VM is running, when it is cloned or Storage vMotioned, the process will not be offloaded via XCOPY to the array. See this blog post here:

VAAI XCOPY not being used with Powered-On Windows VM

So the serial is 6000C29f129e39714f89157a9b73579e.

If I want to do this from the drive letter, it is fairly easy too. So like tell me the drive letter and I will tell you the serial number. This is a combination of get-partition and get-disk.

So the below will return to me the disk that hosts drive E:

get-partition -driveletter E | get-disk

Let’s now look at the virtual disk from a VMware perspective:

Also, 6000C29f129e39714f89157a9b73579e! So perfect, we can make an exact correlation.

So in windows, run get-disk then grab the property SerialNumber and then in vCenter, use get-harddisk against the VM, iterate through the disks and find the one with the matching UUID under extensiondata.backing.uuid.

Fairly simple! And by they way, this process also works for VMFS-based virtual disks too.

I have added a cmdlet in my Pure Storage/VMware PowerShell module that does this for you though.

get-vmdkFromWindowsdisk

It takes in a VM, a Drive Letter (C, E, whatever) and returns the resulting matching virtual disk (what you would find by running get-harddisk).

This can be run interactively, or by entering parameters. It also supports pipeline input, so you can pass the VM in via pipline. Some examples:

Interactively:

Via parameters:

Via pipeline (the VM object can be piped in):

Returning the resulting disk to another cmdlet. In this case taking the disk and expanding it with set-harddisk. Expands it to 500 GB.

This has been added to my PowerShell module found here.

Note that this will work on any storage platform–not just Pure. It also does not require VVols–it will work with VMFS.

It does have a few requirements:

  • The Guest OS must be Windows 2012 or later
  • VMware tools must be installed and online
  • The Disk.EnableUUID on the VM must be either unset, or set to TRUE.

19 Replies to “PowerCLI and VVols Part IV: Correlating a Windows NTFS to a VMDK”

  1. Great minds think a like ;). I did the wmi meathod so it would work with <win2012.

    https://www.ericcsinger.com/powershell-scripting-get-ecsvmwarevirtualdisktowindowslogicaldiskmapping/

    I’m hoping to update my function to return the scsi controller in windows vs VMware, and also show the datastore the vmdk is on. Also thinking about accounting for win storage spaces and maybe even dynamic disks..

    The disk uuid seemed to default to on pre win 2016 and I ended up opening a case to figure it out with VMware when my function did work on a 2016/win10 vm. I wrote a small blog about that too, even have the powercli code to handle it..

  2. Hi Cody,

    Using your script, I can get the details of local disks but I am unable to get the Virtual disk details of RDMs presented. Please help!!!

    1. I haven’t tested this with RDMs, but I do not think it would work, the RDM-based VMDK does not have a UUID in it like standard virtual disks do. I would need to play around with it a bit more. I suspect it would need some code changes.

  3. I have tried using v1.2.0.2 and the newer version 1.3.0.0

    I have vCenter 6.7 (latest); ESXi 6.7 (latest); Purity//FA 5.1.9; a VM is on a standard LUN; VM is Windows 2016 (fully patched); VMtools v10341; no firewall

    When I run interactive:
    PS C:\WINDOWS> get-vmdkFromWindowsDisk
    Please enter in the name of your VM: VMNAME
    Please enter in a drive letter: Z
    You cannot call a method on a null-valued expression.
    At C:\Program Files\WindowsPowerShell\Modules\Cody.PureStorage.FlashArray.VMware\1.2.0.2\Cody.PureStorage.FlashArray.VMware.psm1:345 char:53
    + … ere-Object {$_.ExtensionData.backing.uuid.replace(“-“,””) -eq $VMdisk …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

    Yet if I run the following I get Uuid:
    $vmdisk = get-vm VMNAME | get-harddisk -Name “Hard disk 14”
    $vmdisk.ExtensionData.Backing.Uuid.Replace(“-“,””)

    6000C295bb75bbbaccd48e75136cd441

    1. Hmm I am guessing that nothing is being returned from the VM serial number. but I think I handle that error… If you run get-partition -driveletter in the Windows VM what do you see?

      1. PS C:\Windows\system32> get-partition -driveletter D | Get-Disk

        Number Friendly Name Serial Number HealthStatus OperationalStatus Total Size Partition
        Style
        —— ————- ————- ———— —————– ———- ———-
        10 VMware Virtual disk 6000c297e8718e39572762529a55c47a Healthy Online 80 GB GPT

        1. Weird. I have this same setup in my lab, I will give it a try. Im doing a VMUG and flying back tonight so I may not be able to test until later this week.

          1. Must be something on the VM… I will look more.

            I did:
            PS C:\WINDOWS> get-vmdkFromWindowsDisk -vm (get-vm VvolMV) -driveLetter E

            CapacityGB Persistence Filename
            ———- ———– ——–
            40.000 Persistent …9-d0ee-4f67-942c-8946723a0fec/VvolVM_1.vmdk

            PS C:\WINDOWS> get-vmdkFromWindowsDisk -vm (get-vm LunVM) -driveLetter C

            CapacityGB Persistence Filename
            ———- ———– ——–
            60.000 Persistent [PURE-T1-002] dc1-ad1/LunVM.vmdk

            So it MUST be something in the VM. Thanks again for the quick reply!

          2. Sure thing! Yeah I just tested it on the exact same environment (from what I could see) and it worked. I will dig into the code and see if I can figure anything. If you can find out the difference between the two VMs I’d love to know

  4. Found the problem! Some additional background: I am setting up a 2-node VM Cluster across Physical Hosts. When I connect the Quorum drive to an RDM, the error is seen. For now, I will add the Quorum (RDM) drive last.

    Error (again):
    You cannot call a method on a null-valued expression.
    At C:\Program Files\WindowsPowerShell\Modules\Cody.PureStorage.FlashArray.VMware\1.2.0.2\Cody.PureStorage.FlashArray.VMware.psm1:345 char:53
    + … ere-Object {$_.ExtensionData.backing.uuid.replace(“-“,””) -eq $VMdisk …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

Leave a Reply

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

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