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:
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
Try something like this
$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
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.
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
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?
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
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
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?
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
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!
You're welcome.
Btw, what is the runtime improvement with my version?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
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!
Nice :smileycool:
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference