Today I was asked to extend a disk of a Windows virtual machine. Normally this is a standard procedure and finished within minutes. The hardest part of the procedure is to check the scsi id from within Windows and match the Windows disk to the corresponding virtual disk in the virtual machine’s hardware settings. Unfortunately the vm in question today had only 26 virtual disks spread over 2 virtual SCSI controllers. Same procedure, although you need a little bit more time to figure things out.
When clicking my way through the Windows disk manager I noticed a strange phenomenon. Two of my Windows disks had the same scsi ids. Not only the same target id, but also the same Busnumber!. It turns out that the Busnumber doesn’t identify your SCSI controller, which I was always thinking. After some digging in WMI, I found a SCSIPort property on the W32-DiskDrive WMI class. This property is the one that identifies the SCSI controller.
Oh boy, this daunting task is screaming to be scripted!. After a quick search in my administrators manual (google), I found a blog post from Hugo Peeters. His script uses the same WMI properties to match the Windows disk to its corresponding virtual disk, to calculate the freespace for each virtual disk. Taking advantage of this script I created the following script to create a mapping table between Windows disks and their corresponding virtual disks.
# This script requires PowerCLI 4.0 U1
#
# Create Disk Mapping Table
# Created by Arnim van Lieshout
# Http://www.van-lieshout.com
# Initialize variables
# $VCServerList is a comma-separated list of vCenter servers
$VCServerList = "vCenter01", "vCenter02"
$DiskInfo= @()
$Vm = Read-Host "Enter VMName to create disk mapping for"
# 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}
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
$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 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
}
}
$DiskInfo | Out-GridView
}
else {Write-Host "VM $Vm Not Found"}
Disconnect-VIServer * -Confirm:$false
The drawback of this script is that the user used to run the script must also have Windows administrator privileges on the vm you want to create a mapping table for and that you must be able to remotely query WMI on the vm. So this isn’t going to work out for all vms, e.g. DMZ, but maybe that’s something for a future version.
I recently made some improvements that get rid of these limitations. Read all about it in Match VM and Windows harddisks part 2.
If you have multiple vCenter servers, you don’t have to search which vCenter the vm is registered on, just enter all your vCenter servers to the $VCServerList. Ofcourse you need PowerCLI 4.0 U1 for this feature to work.
Update:
As requested in the comments, below is a sample output of this script:
Update2:
Continue reading Match VM and Windows harddisks part 2 to read about the improvements I made.

on Dec 22nd, 2009 at 10:14 am
Cool stuff!
on Jan 6th, 2010 at 3:09 am
Can you post a sample of the output that you receive when running your script?
on Jan 10th, 2010 at 5:03 pm
Hi dmVI,
I’ve updated my post with a sample output.
on Jan 21st, 2010 at 10:04 am
[...] isolated guests Jan 21st, 2010 by Arnim van Lieshout. A few weeks back I posted an article on matching Windows and VMware disks. Unfortunately this would work only if you could remotely query WMI information from that VM. If [...]
on Feb 3rd, 2010 at 10:02 am
[...] 3rd, 2010 by Arnim van Lieshout. This is a follow up on a post I did a couple of weeks ago to create a mapping table between Windows- and VMware hard disks. In another previous post PowerCLI: Get WMI info from isolated guests, I showed you how to get WMI [...]