Match Windows Drive Letter to VM Disk with PowerCLI

 

Matching OS Drive Letters to VM Disks is definitely something each VMware admin has wanted at some point or another. Unfortunately, it is not the easiest of tasks. Using a suggestion I found in one of the forum posts that the solution might be a combination of two different scripts referenced here and here, I decided to try it out.

After combining and editing the scripts a bit it seems to work really well for me, although I am sure individual results may vary. Anyway here is the script…

 


$DiskInfo= @()
$Vm = "vmname"

$i=0


$disks=Get-VM $vm| Get-HardDisk -DiskType "RawPhysical","RawVirtual"
$logtopart=Get-WmiObject -Class Win32_LogicalDiskToPartition -computername $VM 
$disktopart=Get-WmiObject Win32_DiskDriveToDiskPartition -computername $VM 
$logical=get-wmiobject win32_logicaldisk -computername $Vm
$volume=get-wmiobject win32_volume -computername $Vm
$partition=get-wmiobject win32_diskpartition -computername $Vm
if (($VmView = Get-View -ViewType VirtualMachine -Filter @{"Name" = $Vm})) {
    $WinDisks = Get-WmiObject -Class Win32_DiskDrive -ComputerName $VmView.Name
    foreach ($VirtualSCSIController in ($VMView.Config.Hardware.Device | where {$_.DeviceInfo.Label -match "SCSI Controller"})) {
        foreach ($VirtualDiskDevice in ($VMView.Config.Hardware.Device | where {$_.ControllerKey -eq $VirtualSCSIController.Key})) {
            $VirtualDisk = "" | Select SCSIController, DiskName, SCSI_Id, DiskFile,  DiskSize, WindowsDisk, NAA,drive, volumename
            $VirtualDisk.SCSIController = $VirtualSCSIController.DeviceInfo.Label
            $VirtualDisk.DiskName = $VirtualDiskDevice.DeviceInfo.Label
            $VirtualDisk.SCSI_Id = "$($VirtualSCSIController.BusNumber) : $($VirtualDiskDevice.UnitNumber)"
            $VirtualDisk.DiskFile = $VirtualDiskDevice.Backing.FileName
            $VirtualDisk.DiskSize = $VirtualDiskDevice.CapacityInKB * 1KB / 1GB
            $virtualdisk.naa=$disks|? {$_.name -like $VirtualDiskDevice.DeviceInfo.Label}|select -expand scsicanonicalname




            # Match disks based on SCSI ID
            $DiskMatch = $WinDisks | ?{($_.SCSIPort -2 ) -eq $VirtualSCSIController.BusNumber -and $_.SCSITargetID -eq $VirtualDiskDevice.UnitNumber}
            if ($DiskMatch){
                $VirtualDisk.WindowsDisk = "Disk $($DiskMatch.Index)"
            $i++
            }
            else {Write-Host "No matching Windows disk found for SCSI id $($VirtualDisk.SCSI_Id)"}
            

            $matchdisktopar=$disktopart|Where {$_.Antecedent -eq $diskmatch.__Path}
             $matchlogtopart=$logtopart| Where {$_.Antecedent -eq $matchdisktopar.Dependent}
             $logicalmatch=$logical| where {$_.path.path -eq $matchlogtopart.dependent}
             $VirtualDisk.volumename=$logicalmatch.volumename
             $virtualdisk.drive=$logicalmatch.deviceid


             $DiskInfo += $VirtualDisk
        }
    }
    $DiskInfo | Out-GridView
}
else {Write-Host "VM $Vm Not Found"}

A couple things to note, you obviously need WMI open on the target windows machine, and the permissions to perform WMI calls against said machine.

Here is how it looks once completed.

 

 

The NAA is blank because none of these disks are RDMs, otherwise, NAA would be populated as well. Also for some reason it is not grabbing the C drive….might have to look at that.

 

Regardless it is pretty handy to have in the back pocket when you need it.

 

Let me know what you think

Leave a Reply