VMware Cloud Community
AlbertWT
Virtuoso
Virtuoso

Matching VMDK with WIndows OS drive letter ?

Hi People,

I've got Powershell script below that I need your help to modify it so that it display the Windows Drive letter correctly with the correct VMDK, see the below script:


# This script requires PowerCLI 4.0 U1

#

# Create VM Disk Mapping v2.1

# Created by Arnim van Lieshout

# Http://www.van-lieshout.com

#

# Did you ever got a request to extend a disk on a VM?

# Most probably you were asked to extend Windows disk number x

# Unfortunately this Windows disk number doesn't correspond to the virtual disk number of your VM.

# Finding out which virtual disk in the VM's settings corresponds to this Windows disk can be a cumbersome task.

# Especially when you have multiple SCSI controllers and/or many disks attached to your VM

#

# This script matches Windows disks and their VMware virtual disk counterparts.

# It uses the Invoke-VMScript cmdlet to retrieve WMI information from the Windows guest, so there is no network connection needed to the VM

# This makes the script suitable for isolated guests too (Internal only network, DMZ, or otherwise seperated by firewall).

#

# Multiple vCenter- or ESX(i)-servers can be added to the $VCServerList array, so there's no need to know which host or vCenter manages your VM

# Initialize variables

# $VCServerList is a comma-separated list of vCenter- or ESX(i)-servers

$VCServerList = "PROD-VCENTER-VM01"

$DiskInfo= @()

# Set Default Server Mode to Multiple

Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -Confirm:$false | Out-Null

# Connect to vCenter Server(s)

foreach ($VCServer in $VCServerList) {Connect-VIServer -Server "$VCServer" | Out-Null}

# Ask for VM to create diskmapping for

$Vm = Read-Host "Enter VMName to create disk mapping for"

if (($VmView = Get-View -ViewType VirtualMachine -Filter @{"Name" = $Vm})) {

   # Get the ESX host which the VM is currently running on

   $ESXHost = Get-VMHost -id $VmView.Summary.Runtime.Host

   # Get credentials for host and guest

   $HostCred = $Host.UI.PromptForCredential("Please enter credentials", "Enter ESX host credentials for $ESXHost", "root", "")

   $GuestCred = $Host.UI.PromptForCredential("Please enter credentials", "Enter Guest credentials for $VM", "", "")

   #Get WMI info using Invoke-VMScript, so no network connection to the VM is needed

   $Error.Clear()

   $Out = Invoke-VMScript "wmic path win32_diskdrive get Index, SCSIPort, SCSITargetId /format:csv" -vm $VM -HostCredential $HostCred -GuestCredential $GuestCred -scripttype "bat"

   if (!$error) {

      #Export plaintext WMI disk info to temporary file and import it again using the Import-Csv CmdLet

      $FileName = [System.IO.Path]::GetTempFileName()

      $Out.Substring(2) > $FileName

      $WinDisks = Import-Csv $FileName

      Remove-Item $FileName

      #Create DiskMapping table

      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

            $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

            # Match disks based on Controller and SCSI ID

            $DiskMatch = $WinDisks | ?{($_.SCSIPort – 1) -eq $VirtualSCSIController.BusNumber -and $_.SCSITargetID -eq $VirtualDiskDevice.UnitNumber}

            if ($DiskMatch){

               $VirtualDisk.WindowsDisk = "Disk $($DiskMatch.Index)"

            }

            else {Write-Host "No matching Windows disk found for SCSI id $($VirtualDisk.SCSI_Id)"}

            $DiskInfo += $VirtualDisk

         }

      }

      #Display DiskMapping table

      $DiskInfo | Out-GridView

   }

   else {Write-Host "Error Retrieving WMI info from guest"}

}

else {Write-Host "VM $Vm Not Found"}

Disconnect-VIServer * -Confirm:$false


Note: Credit goes toavlieshout‌ who wrote this script long time ago.


but somehow the result is wrong as can be seen from the screenshot below:

Capture-VMDK.JPG

If the there are multiple drive letter with the same disk capacity size, then it is hard to point which VMDK is for which windows drive letter ?

Thanks in advance.


Thanks.

/* Please feel free to provide any comments or input you may have. */
Tags (2)
4 Replies
AlbertWT
Virtuoso
Virtuoso

Get-PowerCLIVersion

PowerCLI Version
----------------
   VMware vSphere PowerCLI 6.0 Release 2 build 3056836
---------------
Component Versions
---------------
   VMWare AutoDeploy PowerCLI Component 6.0 build 2358282
   VMWare ImageBuilder PowerCLI Component 6.0 build 2358282
   VMware vSphere PowerCLI Component 6.0 build 3052101

$PSVersionTable

Name                           Value                                                                                                                                            
----                           -----                                                                                                                                            
PSVersion                      5.0.10586.0                                                                                                                                      
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}                                                                                                                          
BuildVersion                   10.0.10586.0                                                                                                                                     
CLRVersion                     4.0.30319.42000                                                                                                                                  
WSManStackVersion              3.0                                                                                                                                              
PSRemotingProtocolVersion      2.3                                                                                                                                              
SerializationVersion           1.1.0.1

/* Please feel free to provide any comments or input you may have. */
0 Kudos
LucD
Leadership
Leadership

What OS do you have running in the VM against which you run the report ?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

AlbertWT
Virtuoso
Virtuoso

LucD‌ The OS is Windows Server 2012 R2 while my workstation OS is Win 10.

/* Please feel free to provide any comments or input you may have. */
0 Kudos
JMAYFIELD0779
Contributor
Contributor

Not sure how to incorporate this into the script as written but this will pull the drive letter

#Define computername
    $computer = "smd1oadbkcu0001"

    $ServerDiskToVolume = @(
        Get-WmiObject -Class Win32_DiskDrive -ComputerName $computer | foreach {
       
            $Dsk = $_
            $query = "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='$($_.DeviceID)'} WHERE ResultClass=Win32_DiskPartition"
       
            Get-WmiObject -Query $query -ComputerName $computer | foreach {
           
                $query = "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='$($_.DeviceID)'} WHERE ResultClass=Win32_LogicalDisk"
           
                Get-WmiObject -Query $query -ComputerName $computer | Select DeviceID,
                    VolumeName,
                    @{ label = "SCSITarget"; expression = {$dsk.SCSITargetId} },
                    @{ label = "SCSIBus"; expression = {$dsk.SCSIBus} }
            }
        }
    )

0 Kudos