Hi All,
Can anyone here please assist me with the powershell script if possible to list the VM information like the following format or in CSV format is OK:
SCSI (0:0) VM Hard Disk 1 [R5D23] PRODFSCLUS01-VM/PRODFSCLUS01-VM.vmdk - Windows C: drive - 60 GB
SCSI (1:1) VM Hard Disk 2 [NAS-D76] PRODFSCLUS01-VM/PRODFSCLUS01-VM.vmdk - Windows Q: drive - 1 GB
SCSI (1:2) VM Hard Disk 3 [NAS-D23] PRODFSCLUS01-VM/PRODFSCLUS01-VM.vmdk - Windows G: drive - 1.77 TB
SCSI (1:3) VM Hard Disk 4 [R5D52] PRODFSCLUS01-VM/PRODFSCLUS01-VM.vmdk - Windows H: drive - 1.77 GB
SCSI (1:4) VM Hard Disk 5 [NAS-D19] PRODFSCLUS01-VM/PRODFSCLUS01-VM.vmdk - Windows T: drive - 60 GB
Thanks in advance.
What you are seeing is the default output from that WMI object.
If you want to see different properties, you will have to use the Select-Object cmdlet
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi LucD,
Since you saw the output result n it's clear that only invoke-vmscript gives me a valid output.if I run Get-Ciminstance for a remote computer it doesn't work n I have to use invoke-vmscript to get Get-Ciminstance output.
So how do I modify this script as and use invoke-vmscript.
$compName = 'MyVM'
$volTab = @{}
foreach($disk in (Get-CimInstance -ComputerName $compName -ClassName Win32_DiskDrive)){
foreach($partition in (Get-CimAssociatedInstance -InputObject $disk -ResultClassName Win32_DiskPartition)){
Get-CimAssociatedInstance -InputObject $partition -ResultClassName Win32_LogicalDisk | %{
$volTab.Add("$($disk.SCSIBus):$($disk.SCSITargetId)",($_.DeviceID,$_.VolumeName -join '|'))
}
}
}
$vm = Get-VM -Name $compName
foreach($ctrl in Get-ScsiController -VM $vm){
foreach($disk in (Get-HardDisk -VM $vm | where{$_.ExtensionData.ControllerKey -eq $ctrl.Key})){
$obj = [ordered]@{
VM = $vm.name
HD = $disk.Name
VMDK = $disk.Filename
Device = "$($ctrl.ExtensionData.BusNumber):$($disk.ExtensionData.UnitNumber)"
Drive = ""
Label = ""
}
if($volTab.ContainsKey("$($ctrl.ExtensionData.BusNumber):$($disk.ExtensionData.UnitNumber)")){
$obj.Drive = $volTab["$($ctrl.ExtensionData.BusNumber):$($disk.ExtensionData.UnitNumber)"].Split('|')[0]
$obj.Label = $volTab["$($ctrl.ExtensionData.BusNumber):$($disk.ExtensionData.UnitNumber)"].Split('|')[1]
}
New-Object -TypeName PSObject -Property $obj
}
}
Instead of transferring the complete WMI object, you can do the extraction of the required properties on the target station.
Use this as an example.
It transfers the required data in CSV format, which on the calling side is then converted back to an object.
Which you can use in your script
$user = 'domain\user'
$pswd = 'VMware1!'
$secPswd = ConvertTo-SecureString -String $pswd -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ($user, $secPswd)
$code = @'
$info = foreach($disk in (Get-CimInstance -ClassName Win32_DiskDrive)){
foreach($partition in (Get-CimAssociatedInstance -InputObject $disk -ResultClassName Win32_DiskPartition)){
Get-CimAssociatedInstance -InputObject $partition -ResultClassName Win32_LogicalDisk | select DeviceID, VolumeName,
@{ label = "SCSITarget"; expression = {$disk.SCSITargetId} },
@{ label = "SCSIBus"; expression = {$disk.SCSIPort-2} }
}
}
$info | ConvertTo-Csv -NoTypeInformation -UseCulture
'@
$vm = Get-VM -Name $vmName
$sInvoke = @{
VM = $VM
ScriptType = 'Powershell'
ScriptText = $code
GuestCredential = $cred
}
Invoke-VMScript @sInvoke |
Select -ExpandProperty ScriptOutput |
ConvertFrom-Csv -UseCulture
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I too wanted to determine the association between vmware scsi devices and their windows partitions and drive letters.
Starting with the information gleaned from Map VMware virtual disks and Windows drive volumes with a PowerShell script – 4sysops I knew I could not reliably match Windows and VMWare SCSI bus numbers. I was on my own. I started by generating detailed information from both VMWare and Windows environments. I then summarized each environment's SCSI controller information based on number of SCSI target IDs and total disk space used on all drives. I discovered that once I sorted these summaries, I could see a one-to-one mapping between the VMWare and Windows SCSI controllers. Once I had a valid mapping, I could then update my VMWare report with the missing Windows information (serial number, disk size, number of partitions, drive letters).
If WMI is accessible for the VMs in question, the script will map VMWare to Windows partitions. If WMI is not available, it will at least show you the VMWare side of the equation.
You might want to have a look at the Get-VMGuestDisk cmdlet, new in PowerCLI 12.0.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Get-VMGuestDisk requires vSphere version 7.0 and later.
Seems like Get-VMGuestDisk requires vsphere 7 and later plus vmtool 11.x
That is correct, those are some of the requirements.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi LucD,
Still stuggling to get the Drive letter and disk number on single report.
was tried for class- Win32_DiskDrive command to get the report got failed "WinRM error"
there is any possibility t get the report using vm.Guest.Disks command along with harddisk number
$DiskInfo= @()
foreach ($VMview in Get-VM VMname | Get-View){
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 VMname, SCSIController, DiskName, SCSI_ID, DeviceName, DiskFile, DiskSize
$VirtualDisk.VMname = $VMview.Name
$VirtualDisk.SCSIController = $VirtualSCSIController.DeviceInfo.Label
$VirtualDisk.DiskName = $VirtualDiskDevice.DeviceInfo.Label
$VirtualDisk.SCSI_ID = "$($VirtualSCSIController.BusNumber) : $($VirtualDiskDevice.UnitNumber)"
$VirtualDisk.DeviceName = $VirtualDiskDevice.Backing.DeviceName
$VirtualDisk.DiskFile = $VirtualDiskDevice.Backing.FileName
$VirtualDisk.DiskSize = $VirtualDiskDevice.CapacityInKB * 1KB / 1GB
$DiskInfo +=$VirtualDisk
}}}
$DiskInfo | sort VMname, Diskname | Export-Csv -Path C:\temp\server.csv
ForEach-Object {$vm.Guest.Disks | ForEach-Object {
$VirtualDisk1 = "" | Select-Object -Property Path,capacity
$VirtualDisk1.Path = $_.Path
$VirtualDisk1.Capacity = $_.Capacity
$DiskInfo +=$VirtualDisk1
}
}
Not sure if you have read my previous comments, but there is no fool-proof method to map Guest OS partitions/drives to VMDK files.
With Get-VMGuestDisk this has changed, but there are prerequisites.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thank you for the information ,
finally as per your suggesting have made below script , please help to add to scsicanonicalname and export to csv format.
$volTab = @{}
foreach($disk in (Get-CimInstance -ClassName Win32_DiskDrive)){
foreach($partition in (Get-CimAssociatedInstance -InputObject $disk -ResultClassName Win32_DiskPartition)){
Get-CimAssociatedInstance -InputObject $partition -ResultClassName Win32_LogicalDisk | %{
$volTab.Add("$($disk.SCSIBus):$($disk.SCSITargetId)",($_.DeviceID,$_.VolumeName -join '|'))
}
}
}
foreach($ctrl in Get-ScsiController -VM $vm){
foreach($disk in (Get-HardDisk -VM $vm | where{$_.ExtensionData.ControllerKey -eq $ctrl.Key})){
$obj = [ordered]@{
VM = $vm.name
HD = $disk.Name
VMDK = $disk.Filename
Device = "$($ctrl.ExtensionData.BusNumber):$($disk.ExtensionData.UnitNumber)"
Drive = ""
Label = ""
}
if($volTab.ContainsKey("$($ctrl.ExtensionData.BusNumber):$($disk.ExtensionData.UnitNumber)")){
$obj.Drive = $volTab["$($ctrl.ExtensionData.BusNumber):$($disk.ExtensionData.UnitNumber)"].Split('|')[0]
$obj.Label = $volTab["$($ctrl.ExtensionData.BusNumber):$($disk.ExtensionData.UnitNumber)"].Split('|')[1]
}
New-Object -TypeName PSObject -Property $obj
}
}
So not even Vmware Tools v11 and ESXi v7 can get consistent result from PowerCLI?
There are also some prerequisites on the Guest OS, although it seems to work on several Linux based Guest OS.
Another limiting factor is apparently the filesystem type used, I haven't found a definitive list of which types are supported or not.
Are you seeing issues?
On which Guest OS and which filesystem type?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi LucD,
Below scripts work for me. Can you help me modify the below script to get linux machine details.
param ([ string ]$VMName )
#Define computername
$computer = $VMName
$VMView = Get-VM -Name $computer | Get-View
$ServerDiskToVolume = @(
Get-WmiObject -Class Win32_DiskDrive | foreach {
$Dsk = $_
$query = "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='$($_.DeviceID)'} WHERE ResultClass=Win32_DiskPartition"
Get-WmiObject -Query $query | foreach {
$query = "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='$($_.DeviceID)'} WHERE ResultClass=Win32_LogicalDisk"
Get-WmiObject -Query $query | Select DeviceID,
VolumeName,
@{ label = "SCSITarget"; expression = {$dsk.SCSITargetId} },
@{ label = "SCSIBus"; expression = {$dsk.SCSIBus} }
}
}
)
$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}))
{
$MatchingDisk = @( $ServerDiskToVolume | Where {$_.SCSITarget -eq $VirtualDiskDevice.UnitNumber -and $_.SCSIBus -eq $VirtualSCSIController.BusNumber} )
[pscustomobject]@{
VM = $VMView.Name
#HostName = $VMView.Guest.HostName
DiskFile = $VirtualDiskDevice.Backing.FileName
DiskName = $VirtualDiskDevice.DeviceInfo.Label
DiskSizeGB = $VirtualDiskDevice.CapacityInKB / 1024KB
#SCSIController = $VirtualSCSIController.BusNumber
#SCSITarget = $VirtualDiskDevice.UnitNumber
SCSIid = "$($VirtualSCSIController.BusNumber):$($VirtualDiskDevice.UnitNumber)"
DeviceID = $MatchingDisk.DeviceID
}
}
}
$VMDisks | ft -AutoSize
Thanks
Bikash
I don't know how many times I have to repeat this but there is no foolproof method, before Get-VMGuestDisk, of mapping Guest OS partitions/drives to VMDK.
Your script "works" for a Windows Guest OS and in your specific situation.
The script is partially based on some Windows methods and properties that do not exist in a Linux Guest OS.
There is no straight-forward way to replicate that script for a Linux Guest OS.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi Lucd,
pls assist export the result to csv file, this script is working , only required only export outupt file and due to remote execution policy "Win32_DiskDrive.DeviceID " is not working on our premises,
$volTab = @{}
foreach($disk in (Get-CimInstance -ClassName Win32_DiskDrive)){
foreach($partition in (Get-CimAssociatedInstance -InputObject $disk -ResultClassName Win32_DiskPartition)){
Get-CimAssociatedInstance -InputObject $partition -ResultClassName Win32_LogicalDisk | %{
$volTab.Add("$($disk.SCSIBus):$($disk.SCSITargetId)",($_.DeviceID,$_.VolumeName -join '|'))
}
}
}
foreach($ctrl in Get-ScsiController -VM $vm){
foreach($disk in (Get-HardDisk -VM $vm | where{$_.ExtensionData.ControllerKey -eq $ctrl.Key})){
$obj = [ordered]@{
VM = $vm.name
HD = $disk.Name
VMDK = $disk.Filename
Device = "$($ctrl.ExtensionData.BusNumber):$($disk.ExtensionData.UnitNumber)"
Drive = ""
Label = ""
}
if($volTab.ContainsKey("$($ctrl.ExtensionData.BusNumber):$($disk.ExtensionData.UnitNumber)")){
$obj.Drive = $volTab["$($ctrl.ExtensionData.BusNumber):$($disk.ExtensionData.UnitNumber)"].Split('|')[0]
$obj.Label = $volTab["$($ctrl.ExtensionData.BusNumber):$($disk.ExtensionData.UnitNumber)"].Split('|')[1]
}
New-Object -TypeName PSObject -Property $obj
}
}
The foreach statement doesn't place anything in the pipeline.
It is easier to use the Foreach-Object cmdlet in combination with the Pipeline parameter.
Like this
ForEach-Object -Process {
Get-HardDisk -VM $vm -PipelineVariable disk | where{$_.ExtensionData.ControllerKey -eq $ctrl.Key} |
ForEach-Object -Process {
$obj = [ordered]@{
VM = $vm.name
HD = $disk.Name
VMDK = $disk.Filename
Device = "$($ctrl.ExtensionData.BusNumber):$($disk.ExtensionData.UnitNumber)"
Drive = ""
Label = ""
}
if($volTab.ContainsKey("$($ctrl.ExtensionData.BusNumber):$($disk.ExtensionData.UnitNumber)")){
$obj.Drive = $volTab["$($ctrl.ExtensionData.BusNumber):$($disk.ExtensionData.UnitNumber)"].Split('|')[0]
$obj.Label = $volTab["$($ctrl.ExtensionData.BusNumber):$($disk.ExtensionData.UnitNumber)"].Split('|')[1]
}
New-Object -TypeName PSObject -Property $obj
}
} | Export-Csv -Path .\report.csv -NoTypeInformation -UseCulture
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks for the script. It worked.
Hi Albert,
You can try the below url.
How to match and correlate Windows SCSI Disk IDs with VMware VMDKs - 2ninjas1blog.com
Thanks
V
I know this is an old thread, but I took some snippets from the code included and built something that works with VMware 6.7. The next step is including the process to expand the VMDK and then expand in the OS. I will post that script in a new thread once it is working. Note: I wanted Size, not Lable, but that is an easy change.
$vmName = 'MyVM'
$user = 'domain\user'
$pswd = 'password'
$secPswd = ConvertTo-SecureString -String $pswd -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ($user, $secPswd)
$code = @'
$compName = '.'
$test = $null
foreach($disk in (Get-CimInstance -ComputerName $compName -ClassName Win32_DiskDrive)){
foreach($partition in (Get-CimAssociatedInstance -InputObject $disk -ResultClassName Win32_DiskPartition)){
Get-CimAssociatedInstance -InputObject $partition -ResultClassName Win32_LogicalDisk | %{
$test += "$($disk.SCSIBus):$($disk.SCSITargetId)","=",($_.DeviceID),"|",[math]::round($_.size/1024/1024/1024) -join ""
$test += "`r`n"
}
}
}
$test
'@
$vm = Get-VM -Name $vmName
$sInvoke = @{
VM = $VM
ScriptType = 'Powershell'
ScriptText = $code
GuestCredential = $cred
}
$volTab = @{}
$volTab = Invoke-VMScript @sInvoke | Select -ExpandProperty ScriptOutput | ConvertFrom-StringData
$vm = Get-VM -Name $vmName
foreach($ctrl in Get-ScsiController -VM $vm){
foreach($disk in (Get-HardDisk -VM $vm | where{$_.ExtensionData.ControllerKey -eq $ctrl.Key})){
$obj = [ordered]@{
VM = $vm.name
HD = $disk.Name
VMDK = $disk.Filename
Device = "$($ctrl.ExtensionData.BusNumber):$($disk.ExtensionData.UnitNumber)"
Drive = ""
Size = ""
}
if($volTab.ContainsKey("$($ctrl.ExtensionData.BusNumber):$($disk.ExtensionData.UnitNumber)")){
$obj.Drive = $volTab["$($ctrl.ExtensionData.BusNumber):$($disk.ExtensionData.UnitNumber)"].Split('|')[0]
$obj.Size = $volTab["$($ctrl.ExtensionData.BusNumber):$($disk.ExtensionData.UnitNumber)"].Split('|')[1]
}
New-Object -TypeName PSObject -Property $obj
}
}