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
#
# 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:
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.
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
What OS do you have running in the VM against which you run the report ?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD The OS is Windows Server 2012 R2 while my workstation OS is Win 10.
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} }
}
}
)