VMware Cloud Community
VortaxDaemon666
Contributor
Contributor
Jump to solution

Collect information about each VM on a cluster: EVC configuration, Cluster EVC configuration, BusSharingMode, Connected Floppy/Cdrom drives, Host model vendor, VMkernel enabled vMotion.

Hello all,

I´ve started scripting in 2017 self-taught, so I am still a newbie on this. Due to a consolidation process on all our locations in which we are trying to reduce the number of esxi hosts, I need to provide to the Virtual Machine users which machines may require a downtime or a configuration modification to avoid downtime. What we need is to collect the following information: VM name, Cluster name, EVC configuration,VM BusSharingMode, VM Connected FLoppy/CDrom drives, host, host model vendor, VMK vMotion enabled and save it to a CSV file.

I wrote this script, but it takes too long, specially on larger environments. Is it possible to have this information in a faster way? Please note: I commented the hostmodel part of the script as it was already taking too long to complete.

#Connect to vCenter

$vCenter = "vCenter FQDN"

Connect-VIServer $vcenter

#Create the array

$array = @()

$vms = get-cluster | get-vm

#Loop for BusSharingMode and more VM details

foreach ($vm in $vms)

{

$disks = $vm | Get-ScsiController | Where-Object {$_.BusSharingMode}

$fdisk = $vm | Get-FloppyDrive | Where-Object {$_.ConnectionState.Connected}

$cdrom = $vm | get-cddrive | Where-Object {$_.ConnectionState.Connected}

$VMotion = $vm | get-VMHost | Get-VMHostNetworkAdapter -VMkernel | Select PortGroupName, VmotionEnabled | where Vmotionenabled -eq "true"

#$Hostmodel = $vm | get-VMHost | get-view | where-object {$_.Hardware.SystemInfo.Model}

foreach ($disk in $disks){

$REPORT = New-Object -TypeName PSObject

$REPORT | Add-Member -type NoteProperty -name 'VM Name' -Value $vm.Name

$REPORT | Add-Member -type NoteProperty -name 'Bus Sharing Mode' -Value $disk.BusSharingMode

$REPORT | Add-Member -type NoteProperty -name 'Type' -Value $disk.type

$REPORT | Add-Member -type NoteProperty -name 'Connected Cdrom' -Value $cdrom.ConnectionState.Connected

$REPORT | Add-Member -type NoteProperty -name 'Connected Floppy' -Value $fdisk.ConnectionState.Connected

$Report | Add-Member -type NoteProperty -name 'Cluster' -Value $vm.VMHost.parent

$Report | Add-Member -Type NoteProperty -name 'Model' -Value $Hostmodel.Hardware.SystemInfo.Model

$Report | Add-Member -type NoteProperty -name 'EVC Configuration' -Value $vm.VMHost.Parent.EVCMode

$Report | Add-Member -type NoteProperty -name 'Host Name' -Value $vm.VMHost

$Report | Add-Member -type NoteProperty -name 'VMotion Enabled' -Value $VMotion.Vmotionenabled

$Report | Add-Member -type NoteProperty -name 'PortGroup Label' -Value $VMotion.PortGroupName

$array += $REPORT

}

}

$array | Export-Csv report.csv

Here is how it looks like:

pastedImage_46.png

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

I did some more testing, and the script works for me.
I added some changes that will produce a more meaningful output.

#Connect to vCenter

$vCenter = "vCenter FQDN"

Connect-VIServer $vcenter

Get-View -ViewType ClusterComputeResource -Property Name, Summary | ForEach-Object -Process {

  $cluster = $_

  Get-View -ViewType VirtualMachine -SearchRoot $cluster.MoRef -Property Name, Runtime.Host, Config.Hardware.Device

} |

  ForEach-Object -Process {

  $vm = $_

  $controller = $vm.Config.Hardware.Device | where {$_ -is [VMware.Vim.VirtualController] -and $_.SharedBus}

  $fdisk = $vm.Config.Hardware.Device | where {$_ -is [VMware.Vim.VirtualFloppy]}

  $cdrom = $vm.Config.Hardware.Device | where {$_ -is [VMware.Vim.VirtualCdrom]}

  $esx = Get-View -Id $vm.Runtime.Host -property Name, Hardware.SystemInfo.Model, Config.Vmotion.NetConfig

  $vMotionVmk = $esx.Config.Vmotion.Netconfig.SelectedVnic

  $vMotion = $esx.Config.Vmotion.NetConfig.CandidateVnic | where {$vMotionVmk -contains $_.Key} | Select -ExpandProperty Portgroup

  foreach ($disk in ($vm.Config.Hardware.Device | where {$_ -is [VMware.Vim.VirtualDisk] -and $controller.Device -contains $_.Key})) {

   $ctrl = $controller | where{$_.Key -eq $disk.ControllerKey}

   $obj = [ordered]@{

   'VM Name'   = $vm.Name

   Disk = $disk.DeviceInfo.Label

   Controller = $ctrl.DeviceInfo.Label

   'Bus Sharing Mode'  = $ctrl.SharedBus

   Type   = $ctrl.GetType().Name

   'Connected Cdrom'   = $cdrom.Connectable.Connected

   'Connected Floppy'  = $fdisk.Connectable.Connected

   Cluster   = $cluster.Name

   Model   = $esx.Hardware.SystemInfo.Model

   'EVC Configuration' = $cluster.Summary.CurrentEVCModeKey

   'Host Name'   = $esx.Name

   'VMotion Enabled'   = $vMotionVmk -ne $null

   'PortGroup Label'   = $vMotion -join '|'

   }

   New-Object PSObject -Property $obj

  }

} | Export-Csv .\report.csv -NoTypeInformation -UseCulture


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
12 Replies
LucD
Leadership
Leadership
Jump to solution

Try something like this

#Connect to vCenter

$vCenter = "vCenter FQDN"

Connect-VIServer $vcenter


Get-View -ViewType ClusterComputeResource -Property Name, Summary | ForEach-Object -Process {

  $cluster = $_

  Get-View -ViewType VirtualMachine -SearchRoot $cluster.MoRef -Property Name, Runtime.Host, Config.Hardware.Device

} |

  ForEach-Object -Process {

  $vm = $_

  $controller = $_.Config.Hardware.Device | where {$_ -is [VMware.Vim.VirtualController] -and $_.SharedBus}

  $fdisk = $_.Config.Hardware.Device | where {$_ -is [VMware.Vim.VirtualFloppy] -and $_.Connectable.Connected}

  $cdrom = $_.Config.Hardware.Device | where {$_ -is [VMware.Vim.VirtualCdrom] -and $_.Connectable.Connected}

  $esx = Get-View -Id $vm.Runtime.Host -property Name, Hardware.SystemInfo.Model, Config.Vmotion.NetConfig

  $vMotionVmk = $esx.Config.Vmotion.Netconfig.SelectedVnic

  $vMotion = $esx.Config.Vmotion.NetConfig.CandidateVnic | where {$vmk -contains $_.Key} | Select -ExpandProperty Portgroup

  foreach ($disk in ($vm.Config.Hardware.Device | where {$_ -is [VMware.Vim.VirtualDisk] -and $controller.Device -contains $_.Key})) {

   $obj = [ordered]@{

   'VM Name'   = $vm.Name

   'Bus Sharing Mode'  = $controller.SharedBus

   Type   = $controller.GetType().Name

   'Connected Cdrom'   = $cdrom.Connectable.Connected

   'Connected Floppy'  = $fdisk.Connectable.Connected

   Cluster   = $cluster.Name

   Model   = $esx.Hardware.SystemInfo.Model

   'EVC Configuration' = $cluster.Summary.CurrentEVCModeKey

   'Host Name'   = $esx.Name

   'VMotion Enabled'   = $vMotionVmk -ne $null

   'PortGroup Label'   = $vMotion -join '|'

   }

   New-Object PSObject -Property $obj

  }

} | Export-Csv report.csv -NoTypeInformation -UseCulture


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
VortaxDaemon666
Contributor
Contributor
Jump to solution

Hello Luc,

Thanks for your help! There is just one issue, it seems it does not display any information at all. Tried to use out-gridview or just deleted the last entry to check if it display any information on the powercli window without any success.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

What PowerShell version (check $PSVersionTable) and PowerCLI version (check with Get-Module -Name VMware* -ListAvailable) are you using?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
VortaxDaemon666
Contributor
Contributor
Jump to solution

Powershell: PSVersion-5.1.14393.2248

powercli: 6.5.0.4... VMware.VimAutomation.Sdk            Get-PSVersion

I just saw there is a new huge release. Should I use it instead?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

This is indeed a somewhat older version, and yes, I would suggest to do an upgrade (latest is 10.2.0).

But I don't think your current version would make a difference for the script.

Are you getting any error messages?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
LucD
Leadership
Leadership
Jump to solution

I did some more testing, and the script works for me.
I added some changes that will produce a more meaningful output.

#Connect to vCenter

$vCenter = "vCenter FQDN"

Connect-VIServer $vcenter

Get-View -ViewType ClusterComputeResource -Property Name, Summary | ForEach-Object -Process {

  $cluster = $_

  Get-View -ViewType VirtualMachine -SearchRoot $cluster.MoRef -Property Name, Runtime.Host, Config.Hardware.Device

} |

  ForEach-Object -Process {

  $vm = $_

  $controller = $vm.Config.Hardware.Device | where {$_ -is [VMware.Vim.VirtualController] -and $_.SharedBus}

  $fdisk = $vm.Config.Hardware.Device | where {$_ -is [VMware.Vim.VirtualFloppy]}

  $cdrom = $vm.Config.Hardware.Device | where {$_ -is [VMware.Vim.VirtualCdrom]}

  $esx = Get-View -Id $vm.Runtime.Host -property Name, Hardware.SystemInfo.Model, Config.Vmotion.NetConfig

  $vMotionVmk = $esx.Config.Vmotion.Netconfig.SelectedVnic

  $vMotion = $esx.Config.Vmotion.NetConfig.CandidateVnic | where {$vMotionVmk -contains $_.Key} | Select -ExpandProperty Portgroup

  foreach ($disk in ($vm.Config.Hardware.Device | where {$_ -is [VMware.Vim.VirtualDisk] -and $controller.Device -contains $_.Key})) {

   $ctrl = $controller | where{$_.Key -eq $disk.ControllerKey}

   $obj = [ordered]@{

   'VM Name'   = $vm.Name

   Disk = $disk.DeviceInfo.Label

   Controller = $ctrl.DeviceInfo.Label

   'Bus Sharing Mode'  = $ctrl.SharedBus

   Type   = $ctrl.GetType().Name

   'Connected Cdrom'   = $cdrom.Connectable.Connected

   'Connected Floppy'  = $fdisk.Connectable.Connected

   Cluster   = $cluster.Name

   Model   = $esx.Hardware.SystemInfo.Model

   'EVC Configuration' = $cluster.Summary.CurrentEVCModeKey

   'Host Name'   = $esx.Name

   'VMotion Enabled'   = $vMotionVmk -ne $null

   'PortGroup Label'   = $vMotion -join '|'

   }

   New-Object PSObject -Property $obj

  }

} | Export-Csv .\report.csv -NoTypeInformation -UseCulture


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
VortaxDaemon666
Contributor
Contributor
Jump to solution

Hello Luc,

It works very well!! Thanks a lot.

I was wondering if I modify it to retrieve all VMs information and not just the ones with those settings enabled, would it take too long to complete? 

0 Kudos
LucD
Leadership
Leadership
Jump to solution

It is running already through all VMs, just not doing the extra calculations if the VM doesn't qualify.

The duration of the run would depend on how many VMs you are talking about.
And which properties you would like to report on for all VMs?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
VortaxDaemon666
Contributor
Contributor
Jump to solution

Same properties. But on second though, I actually prefer the way you did it. For the clusters where there are no VMs with these constraints I can write a quick script to retrieve the vMotion information and that´s it.

Again, many thanks for your help!

0 Kudos
LucD
Leadership
Leadership
Jump to solution

You're welcome.
Btw, what is the runtime improvement with my version?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
VortaxDaemon666
Contributor
Contributor
Jump to solution

8.349 seconds after login on a environment with 2449 Virtual machines :smileygrin:

Compared to my 20-30 min script on the same environment. I need to study a lot more!

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Nice :smileycool:


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos