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 info from a guest without using the guest’s network. I used this technique to enhance my mapping table script.
You need to login to both the ESX host and the Windows guest seperately, so there’s no more need for the user running the script to have administrator permissions on the guest. Multiple domains aren’t an issue anymore and neither are firewalls.
Remember: this only works when VMware Tools are installed
# This script requires PowerCLI 4.0 U1 # # Create Disk Mapping Table v2.0 # 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= @() # 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} $Vm = Read-Host "Enter VMName to create disk mapping for" if (($VmView = Get-View -ViewType VirtualMachine -Filter @{"Name" = $Vm})) { $ESXHost = Get-VMHost -id $VmView.Summary.Runtime.Host # Get credentials $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 $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) { $FileName = [System.IO.Path]::GetTempFileName() $Out.Substring(2) > $FileName $WinDisks = Import-Csv $FileName Remove-Item $FileName 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 "Error Retrieving WMI info from guest"} } else {Write-Host "VM $Vm Not Found"} Disconnect-VIServer * -Confirm:$false
Since I like using the VESI, I integrated the script into the EcoShell with just a few minor adjustments. You can also use PowerGUI instead.
Just create a new Script node and paste the following code:
if ($global:defaultviservers) { $DiskInfo= @() $Vm = Read-Host "Enter VMName to create disk mapping for" if (($VmView = Get-View -ViewType VirtualMachine -Filter @{"Name" = $Vm})) { $ESXHost = Get-VMHost -id $VmView.Summary.Runtime.Host $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", "", "") $Out = Invoke-VMScript "wmic path win32_diskdrive get Index, SCSIPort, SCSITargetId /format:csv" -vm $VM -HostCredential $HostCred -GuestCredential $GuestCred -scripttype "bat" $FileName = [System.IO.Path]::GetTempFileName() $Out.Substring(2) > $FileName $WinDisks = Import-Csv $FileName Remove-Item $FileName 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 $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 } else {[System.Windows.Forms.MessageBox]::Show("VM $Vm Not Found",'Virtual Machine not Found',[System.Windows.Forms.MessageBoxButtons]::OK,[System.Windows.Forms.MessageBoxIcon]::Information) | Out-Null} } Else { [System.Windows.Forms.MessageBox]::Show('You must connect to one or more hosts before you can use this node. Please click on the ''Managed Hosts'' node of the VMware PowerPack, connect to one or more of the servers you have configured there, and then try again.','Connection not established',[System.Windows.Forms.MessageBoxButtons]::OK,[System.Windows.Forms.MessageBoxIcon]::Information) | Out-Null }
Or just download my VESI/PowerGui PowerPack.
Example output from the EcoShell:

Related posts:
- Match VM and Windows harddisks using PowerCLI 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...
- PowerCLI: Get WMI info from isolated guests 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....
- Setting custom attributes with VMware PowerCLI Last week I wanted to extend my vCenter with some extra custom attributes on my VMs. This would extend the usability of the Export List feature for reporting purposes....
- List HBA WWPNs and LUNs using Powershell Lately I’m moving around my VMs and storage luns between my ESX clusters a lot to accomplish a complete redesign of my Virtual Infrastructure. At some point I got...
- PowerShell / PowerCLI linkage Since I started looking into PowerShell and PowerCLI, I gathered a couple of links which I found interesting and useful. I needed a way for them to be accessible...

on Feb 3rd, 2010 at 11:50 pm
[...] I recently made some improvements that get rid of these limitations. Read all about it in Match VM and Windows harddisks part 2. [...]