I’ve created a script based on input from various VMware powercli forums that builds a listing of VMDK files/datastores for a given Windows VM, along with pieces of corresponding WMI information from within the Windows server guest. This part of the script seems to be working reliably, here is the script so far:
# Add Snap-in for VMware PowerCLI
Add-PSSnapin VMware.VimAutomation.Core | Out-Null
# Prompt for vCenter and CSV input file details
$vCenter = Read-Host "vCenter Name or IP"
$CSVLocation = Read-Host "Full path to .csv file"
Connect-VIServer -Server $vCenter | Out-Null
# Import list of VMs from input file
$CSV = Import-Csv $CSVLocation | sort VM -Unique
# Loop through VMs from CSV and match VMDKs to Windows drives
$results = foreach($computer in $CSV)
{
$computer = $computer.VM
$VMView = Get-VM -Name $computer | Get-View
$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} }
}
}
)
# Loop through all the SCSI controllers on the VM and find those that match the Controller and Target
$VMDisks = 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}))
{
#Match up the VM to a logical disk
$MatchingDisk = @( $ServerDiskToVolume | Where {$_.SCSITarget -eq $VirtualDiskDevice.UnitNumber -and $_.SCSIBus -eq $VirtualSCSIController.BusNumber} )
#Build a custom object to hold results
[pscustomobject]@{
VM = $VMView.Name
HostName = $VMView.Guest.HostName
DiskFile = $VirtualDiskDevice.Backing.FileName
DiskName = $VirtualDiskDevice.DeviceInfo.Label
DiskSizeGB = [math]::Round($VirtualDiskDevice.CapacityInKB/1024KB,0)
SCSIController = $VirtualSCSIController.BusNumber
SCSITarget = $VirtualDiskDevice.UnitNumber
CurrentDriveLetter = $MatchingDisk.DeviceID
}
}
}
$VMDisks
}
# Output results to console
$results | Format-Table -AutoSize
# Disconnect from vCenter
Disconnect-VIServer -Server $vCenter -Confirm:$false
Here is a sample of the input CSV file:
VM,Datastore,DiskPath,DriveLetter,SizeGB,FullPath SERVER01,DTS001,SERVER01/SERVER01.vmdk,T,5,[DTS001] SERVER01/SERVER01.vmdk SERVER02,DTS002,SERVER02/SERVER02_1.vmdk,T,5,[DTS002] SERVER02/SERVER02_1.vmdk
Here is a sample of the output that the script returns:
VM HostName DiskFile DiskName DiskSizeGB SCSIController SCSITarget CurrentDriveLetter -- -------- -------- -------- ---------- -------------- ---------- ------------------ SERVER01 SERVER01.DOMAIN.COM [DTS001] SERVER01/SERVER01_3.vmdk Hard disk 1 40 0 0 C: SERVER01 SERVER01.DOMAIN.COM [DTS001] SERVER01/SERVER01.vmdk Hard disk 2 5 0 1 Q: SERVER02 SERVER02.DOMAIN.COM [DTS002] SERVER02/SERVER02.vmdk Hard disk 1 60 0 0 C: SERVER02 SERVER02.DOMAIN.COM [DTS002] SERVER02/SERVER02_1.vmdk Hard disk 2 5 0 1 Q:
I need help to modify the script to, based on the CSV information, change the drive letter for the matching VMDK disk (assuming it is different). Just to reiterate, the CSV has the “correct” drive letter in the “DriveLetter” column.
I know something like this can take a current drive letter in the Windows guest and assign a new one, but I’m not sure how to fit this into my script at this point:
Get-WmiObject -Class Win32_Volume -ComputerName $VM1 -Filter "DriveLetter='$oldletter'" | Set-WmiInstance -Arguments @{DriveLetter=$newletter}
I’m just not sure how to feed the matched information from the script above into the $oldletter variable and the CSV information into the $newletter variable.
Any assistance in finishing this off would be greatly appreciated.
Drew