VMware Cloud Community
ganapa2000
Hot Shot
Hot Shot

Failed to match the disk for RDM disks

Hi,

I am seeing Failed to match the disk for RDM disks on few servers.

I can see the serial number of disk at Windows level, but in the script, it is failing.

Attached script and output.

Please help

5 Replies
LucD
Leadership
Leadership

I think I already told you that there is no fool-proof script that can map guest OS partitions/drives to VMDK.

This, the RDM, is just one example of that.

Sorry, can't help you with the impossible


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

AlbertWT
Virtuoso
Virtuoso

ganapa​, what was the issue on the script you got?

This is the last known script that I have used before created by avlieshout​:

# 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 = "10.10.10.10"

$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

Hope that helps.

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

Hi LucD​, yes, you are right, there is no exact way without documenting the VMDK yourself manually when you built the VM.

Is there any reason for this one or this is proprietary VMware or Microsoft method in assigning the number?

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

Yes, afaik this is proprietary code.

Every time I think I had found the rule, there was another exception.


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

AlbertWT
Virtuoso
Virtuoso

Yes, even by using two different script like this for another example,

$vm = "NameOfYour-VM"

Function get-match($vm) {

    $VM = get-vm $vm

    $VMSummaries = @()

    $DiskMatches = @()

    $VMView = $VM | Get-View

    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 })) {

            $VMSummary = "" | Select VM, HostName, PowerState, DiskFile, DiskName, DiskSize, SCSIController, SCSITarget

            $VMSummary.VM = $VM.Name

            $VMSummary.HostName = $VMView.Guest.HostName

            $VMSummary.PowerState = $VM.PowerState

            $VMSummary.DiskFile = $VirtualDiskDevice.Backing.FileName

            $VMSummary.DiskName = $VirtualDiskDevice.DeviceInfo.Label

            $VMSummary.DiskSize = $VirtualDiskDevice.CapacityInKB * 1KB

            $VMSummary.SCSIController = $VirtualSCSIController.BusNumber

            $VMSummary.SCSITarget = $VirtualDiskDevice.UnitNumber

            $VMSummaries += $VMSummary

        }

    }


    $Disks = Get-WmiObject -Class Win32_DiskDrive -ComputerName $VM.Name -Credential $Credential

    $Diff = $Disks.SCSIPort | sort-object -Descending | Select -last 1

    foreach ($device in $VMSummaries) {

        $Disks | % { if ((($_.SCSIPort - $Diff) -eq $device.SCSIController) -and ($_.SCSITargetID -eq $device.SCSITarget)) {

                $DiskMatch = "" | Select VMWareDisk, VMWareDiskSize, WindowsDeviceID, WindowsDiskSize

                $DiskMatch.VMWareDisk = $device.DiskName

                $DiskMatch.WindowsDeviceID = $_.DeviceID.Substring(4)

                $DiskMatch.VMWareDiskSize = $device.DiskSize / 1gb

                $DiskMatch.WindowsDiskSize = [decimal]::round($_.Size / 1gb)

                $DiskMatches += $DiskMatch

            

            }

        }

    }

    $DiskMatches | export-csv -path "C:\temp\$($VM.Name)drive_matches.csv" -NoTypeInformation

    return $DiskMatches

}


$WinDevIDs = get-match $vm

$DiskDrivesToDiskPartition = Get-WmiObject -Class Win32_DiskDriveToDiskPartition -ComputerName $vm

$WinDevsToDrives = @()

foreach ($ID in $WinDevIDs) {

    $PreRes = $null

    $PreRes = $DiskDrivesToDiskPartition.__RELPATH -match $ID.WindowsDeviceID

    for ($i = 0; $i -lt $PreRes.Count; $i++) {

        $matches = $null

        $WinDev = "" | Select PhysicalDrive, DiskAndPart

        $PreRes[$i] -match '.*(Disk\s#\d+\,\sPartition\s#\d+).*'

        $WinDev.PhysicalDrive = $ID.WindowsDeviceID

        $WinDev.DiskAndPart = $matches[1]

        $WinDevsToDrives += $WinDev

    }

}


$LogicalDiskToPartition = Get-WmiObject -Class Win32_LogicalDiskToPartition -ComputerName $vm

$final = @()

foreach ($drive in $WinDevsToDrives) {

    $matches = $null

    $WinDevVol = "" | Select PhysicalDrive, DiskAndPart, VolumeLabel

    $WinDevVol.PhysicalDrive = $drive.PhysicalDrive

    $WinDevVol.DiskAndPart = $drive.DiskAndPart

    $Res = $LogicalDiskToPartition.__RELPATH -match $drive.DiskAndPart

    $Res[0] -match '.*Win32_LogicalDisk.DeviceID=\\"([A-Q]\:).*'

    if ($matches) {

        $WinDevVol.VolumeLabel = $matches[1]

    }

    $final += $WinDevVol


}

$final | Export-Csv -Path "C:\temp\$($vm)volume_matches.csv" -NoTypeInformation

Sometimes the Windows Drive letter is not matchable.

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