How to trace a VM disk to a guest disk
No voodoo involved. If you’re a Linux person then the mechanics of this process should work for you also. For Windows people I'll include some PowerShell code that should work in Server 2008 and later (requires PowerCLI, and uses WMI).
How to trace a disk:
Works great in my environment but certainly not claiming it will work everywhere. What I know for sure:
This code is just hacked together. No error handling - if it bombs it bombs. Just connect to your VI server (script does NOT do this) and edit $vmName to match the server you want to check.
Enjoy :smileymischief:
$vmName = "cheezburger"
## modification below here not necessary to run ##
#get windows disks via wmi
$cred = if ($cred){$cred}else{Get-Credential}
$win32DiskDrive = Get-WmiObject -Class Win32_DiskDrive -ComputerName $vmName -Credential $cred
#get vm hard disks and vm datacenter and virtual disk manager via PowerCLI
#does not connect to a vi server for you! you should already be connected to the appropraite vi server.
$vmHardDisks = Get-VM -Name $vmName | Get-HardDisk
$vmDatacenterView = Get-VM -Name $vmName | Get-Datacenter | Get-View
$virtualDiskManager = Get-View -Id VirtualDiskManager-virtualDiskManager
#iterates through each windows disk and assign an alternate disk serial number value if not a vmware disk model
#required to handle physical mode RDMs, otherwise this should not be needed
foreach ($disk in $win32DiskDrive)
{
#add a AltSerialNumber NoteProperty and grab the disk serial number
$disk | Add-Member -MemberType NoteProperty -Name AltSerialNumber -Value $null
$diskSerialNumber = $disk.SerialNumber
#if disk is not a VMware disk set the AltSerialNumber property
if ($disk.Model -notmatch 'VMware Virtual disk SCSI Disk Device')
{
#if disk serial number is 12 characters convert it to hex
if ($diskSerialNumber -match '^\S{12}$')
{
$diskSerialNumber = ($diskSerialNumber | foreach {[byte[]]$bytes = $_.ToCharArray(); $bytes | foreach {$_.ToString('x2')} } ) -join ''
}
$disk.AltSerialNumber = $diskSerialNumber
}
}
#iterate through each vm hard disk and try to correlate it to a windows disk
#and generate some results!
$results = @()
foreach ($vmHardDisk in $vmHardDisks)
{
#get uuid of vm hard disk / and remove spaces and dashes
$vmHardDiskUuid = $virtualDiskManager.queryvirtualdiskuuid($vmHardDisk.Filename, $vmDatacenterView.MoRef) | foreach {$_.replace(' ','').replace('-','')}
#match vm hard disk uuid to windows disk serial number
$windowsDisk = $win32DiskDrive | where {$_.SerialNumber -eq $vmHardDiskUuid}
#if windowsDisk not found then try to match the vm hard disk ScsiCanonicalName to the AltSerialNumber set previously
if (-not $windowsDisk)
{
$windowsDisk = $win32DiskDrive | where {$_.AltSerialNumber -eq $vmHardDisk.ScsiCanonicalName.substring(12,24)}
}
#generate a result
$result = "" | select vmName,vmHardDiskDatastore,vmHardDiskVmdk,vmHardDiskName,windowsDiskIndex,windowsDiskSerialNumber,vmHardDiskUuid,windowsDiskAltSerialNumber,vmHardDiskScsiCanonicalName
$result.vmName = $vmName.toupper()
$result.vmHardDiskDatastore = $vmHardDisk.filename.split(']')[0].split('[')[1]
$result.vmHardDiskVmdk = $vmHardDisk.filename.split(']')[1].trim()
$result.vmHardDiskName = $vmHardDisk.Name
$result.windowsDiskIndex = if ($windowsDisk){$windowsDisk.Index}else{"FAILED TO MATCH"}
$result.windowsDiskSerialNumber = if ($windowsDisk){$windowsDisk.SerialNumber}else{"FAILED TO MATCH"}
$result.vmHardDiskUuid = $vmHardDiskUuid
$result.windowsDiskAltSerialNumber = if ($windowsDisk){$windowsDisk.AltSerialNumber}else{"FAILED TO MATCH"}
$result.vmHardDiskScsiCanonicalName = $vmHardDisk.ScsiCanonicalName
$results += $result
}
#sort and then output the results
$results = $results | sort {[int]$_.vmHardDiskName.split(' ')[2]}
$results | ft -AutoSize
FMON, thanks for the awesome script. I am however having some issues with it. It looks like I'm only getting the "windowsDiskIndex, windowsDiskSerialNumber, & windowsDiskAltSerialNumber" for only the non RDM disks...
vmHardDiskName windowsDiskIndex windowsDiskSerialNumber vmHardDiskUuid windowsDiskAltSerialNumber vmHardDiskScsiCanonicalName
-------------- ---------------- ----------------------- -------------- -------------------------- ---------------------------
Hard disk 1 0 6000c299634fc97de071566b9f071359 6000C299634fc97de071566b9f071359
Hard disk 2 FAILED TO MATCH FAILED TO MATCH 6000C297d78efef9c646ebe808fdb741 FAILED TO MATCH naa.600601605f61310011e4a934806be511
Hard disk 3 FAILED TO MATCH FAILED TO MATCH 6000C29f7365ddbc290d9db73d4f9628 FAILED TO MATCH naa.600601605f6131001711716a7d6be511
Hard disk 4 FAILED TO MATCH FAILED TO MATCH 6000C290747b10d4b2c197f6853e80ae FAILED TO MATCH naa.600601605f61310079cfc466806be511
Hard disk 5 FAILED TO MATCH FAILED TO MATCH 6000C295dff4205885458efd9ea614e0 FAILED TO MATCH naa.600601605f6131007959baf37d6be511
Hard disk 6 1 6000c29775446efa07b7387b1d46441e 6000C29775446efa07b7387b1d46441e
Hard disk 7 2 6000c2973503e05024a2795874933066 6000C2973503e05024a2795874933066
Hi FMON,
excellent script, close to what I was looking for.
I found this issue with pRDM : "FAILED TO MATCH" on "windowsDiskIndex" and "windowsDiskSerialNumber"
Any idea mate?
FMON ,
Thanks for sharing the script.
With no RDM in the VM attached, does the windowsDiskAltSerialNumber and vmHardDiskScsiCanonicalName column supposed to be empty?
Hello,
Although I really like the solution, and I think I know the answer to this question, but then just to confirm....
Is there any way to map the VM .vmdk file to a guest disk, only based on the info vCenter and the VM tools provide?
(So with no access to the VM or its WMI information)
Just to confirm.
Cheers,
Harold
No (but you knew that :smileygrin:)
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
First of all thanks for your script FMON. Earlier this year I had the problem to match OS disk with vm vHDD while writing an autoextend script for our windows servers.
I then tried your script. It didn't work for my environment, but it helped me a lot to solve my problem.
Here is the link to my script proposal, like FMONs, just hacked together with no real error handling and I guess with many need for improvement.
Perhaps this script helps some of you or somebody wants to improve it. I'm open to suggestions!
Match OS Disk - vmware vHDD · GitHub
The script uses:
- Powercli
- Powershell
- WMI
Prerequisites:
- disk.EnableUUID="true"
- User for Invoke-VMScript with appropriate rights
- current vmware tools version
Cheers!
Great script! Took ages to find something like this.
Thanks for sharing.
José