VMware Cloud Community
ganesha31
Enthusiast
Enthusiast
Jump to solution

Get VM, Host and Cluster info

Hi, I'm new to this and I'm looking for a script which pulls the following attributes and exports them to an excel.

Input -> variable with all vCenters (list)

Looking for

VM Name, Host Name, Cluster Name, VM Power State, Host CPUs, Host CPU Type, Host Memory, Cluster Memory, HyperThread, VM Sockets, VM Cores Per Socket, Logical CPUs (VM Sockets * VM Cores Per Socket)

I tried but was able to pull the Host related data in one script and VM related in other. I would like to combine both of these into one script, but was unsuccessful. Can someone please help me with this?

Thanks, 
Ganesh

1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

When I mentioned API I was referring to the SOAP API, not the REST API.

In any case, try the following

$sCluster = @{

    ViewType = 'ClusterComputeResource'

    Property = 'Name'

    PipelineVariable = 'cluster'

}

$sVMHost = @{

    ViewType = 'HostSystem'

    Property = 'Name','Runtime.PowerState','Summary.Hardware'

    PipelineVariable = 'esx'

}

$sVM = @{

    ViewType = 'VirtualMachine'

    Property = 'Name','Summary.Runtime.PowerState','Config.Hardware'

    PipelineVariable = 'vm'

    Filter = @{'Summary.Config.Template'='False'}

}

Get-View @sCluster |

ForEach-Object -Process {

    Get-View @sVMHost -SearchRoot $cluster.MoRef |

    ForEach-Object -Process {

        Get-View @sVM -SearchRoot $esx.MoRef  |

        ForEach-Object -Process {

            $vm | Select @{N='Cluster';E={$cluster.Name}},

                @{N='VMHost';E={$esx.Name}},

                @{N='HostState';E={$esx.RunTime.PowerState}},

                @{N='HostCPU';E={$esx.Summary.Hardware.NumCpuCores}},

                @{N='CPUType';E={$esx.Summary.Hardware.CpuModel}},

                @{N='MemoryMB';E={[math]::Round($esx.Summary.Hardware.MemorySize/1KB)}},

                @{N='HyperThread';E={-not ($esx.Summary.Hardware.NumCpuCores -eq $esx.Summary.Hardware.NumCpuThreads)}},

                @{N='VM';E={$vm.Name}},

                @{N='VMState';E={$vm.Summary.Runtime.PowerState}},

                @{N='VMSockets';E={$vm.Config.Hardware.NumCpu/$vm.Config.Hardware.NumCoresPerSocket}},

                @{N='VMCoresPerSocket';E={$vm.Config.Hardware.NumCoresPerSocket}},

                @{N='VMLogicalCPUs';E={$vm.Config.Hardware.NumCpu}},

                @{N='VMTotalMemoryGB';E={$vm.Config.Hardware.MemoryMB/1KB}}

        }

    }

}


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

View solution in original post

36 Replies
LucD
Leadership
Leadership
Jump to solution

Can you share the scripts you already have?


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

0 Kudos
ganesha31
Enthusiast
Enthusiast
Jump to solution

Thanks for the quick response.. Here you go
 
$oStatsObjects = @()
foreach($vm in Get-VM  | Where-object {$_.powerstate -eq "poweredon"})
{
# write-host $vm
$esxHost = Get-VMHost -VM $vm
$esxVM = Get-VM -Name $vm | Select-Object -Property Name,PowerState,NumCPU,NumCoresPerSocket,MemoryGB
$oObject = New-Object PSObject -Property @{
HostName = $esxHost.Name
Cluster = $esxHost.Parent
HostState = $esxHost.PowerState
HostCPUs = $esxHost.NumCpu
CPUType = $esxHost.ProcessorType
Memory = $esxHost.MemoryTotalMB
HyperThread = $esxHost.HyperthreadingActive
VMName = $esxVM.Name
VMState = $esxVM.PowerState
VMSockets = $esxVM.NumCPU
VMCoresPerSocket = $esxVM.config.hardware.NumCoresPerSocket
VMLogicalCPUs = $esxVM.config.hardware.NumCPU * $esxVM.config.hardware.NumCoresPerSocket
VMTotalMemory = $esxVM.MemoryGB
 
write-host  "Exporting Data for Host - VM : $HostName - $vm"
$oStatsObjects += $oObject
$oObject = $null
}
0 Kudos
ganesha31
Enthusiast
Enthusiast
Jump to solution

Looks like I was able to get the solution

$oStatsObjects = @()
foreach($vm in $vms)
{
write-host $vm
$esxHost = Get-VMHost -VM $vm
$esxVM = Get-VM -Name $vm | Select-Object -Property Name,PowerState,NumCPU,NumCoresPerSocket,MemoryGB
$esxVMCoresPerSocket = Get-View -ViewType VirtualMachine -filter @{"Name"=$vm} | Select-Object -Property config
write-host $esxVM
$oObject = New-Object PSObject -Property @{
HostName = $esxHost.Name
Cluster = $esxHost.Parent
HostState = $esxHost.PowerState
HostCPUs = $esxHost.NumCpu
CPUType = $esxHost.ProcessorType
Memory = $esxHost.MemoryTotalMB
HyperThread = $esxHost.HyperthreadingActive
VMName = $esxVM.Name
VMState = $esxVM.PowerState
VMSockets = $esxVM.NumCPU
VMCoresPerSocket = $esxVMCoresPerSocket.config.hardware.NumCoresPerSocket
VMLogicalCPUs = $esxVM.NumCPU * $esxVMCoresPerSocket.config.hardware.NumCoresPerSocket
VMTotalMemory = $esxVM.MemoryGB
 
$oStatsObjects += $oObject
$oObject = $null
}
 
$csvExport = $oStatsObjects | ConvertTo-Csv -outvariable $csvOut -notypeinformation
$csvExport[0..($csvExport.count -1)] | foreach-object {add-content -value $_ -path $outFileName}
$oStatsObjects=$null
0 Kudos
ganesha31
Enthusiast
Enthusiast
Jump to solution

However, I noticed that "VMCoresPerSocket" is returning "System.Object[]" for few. Can you please help me on how to handle this? Thanks in advance!

VMCoresPerSocket = $esxVMCoresPerSocket.config.hardware.NumCoresPerSocket

0 Kudos
LucD
Leadership
Leadership
Jump to solution

That could mean that more than one VM is returned on the Get-View cmdlet.

Remember that the right-hand operator for an entry in the Filter hash table, is a RegExexpression.

If, for example, the value in $vm is 'VM', it will return the VM with the name 'VM', but also 'VM1' and 'MyVM'.

By using RegEx anchors you can filter on an exact match.

$esxVMCoresPerSocket = Get-View -ViewType VirtualMachine -filter @{'Name'="^$vm$"} | Select-Object -Property config


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

ganesha31
Enthusiast
Enthusiast
Jump to solution

Thanks a lot for the explanation! I will give it a try and will update you here. Once again thank you so much for the help!
0 Kudos
ganesha31
Enthusiast
Enthusiast
Jump to solution

Perfect! It is working as expected now. Thank you once again!
0 Kudos
ganesha31
Enthusiast
Enthusiast
Jump to solution

I have around 16 vCenters and 15K VMs in total. This script takes forever to run and is very slow. Is there any better way to pull the data quickly? Please advise.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

There are a few options to improve the execution time.

- use Get-View and EXtensionData

- use the vSphere API directly instead of the PowerCLI cmdlets

- run multiple background job to spread the load


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

0 Kudos
ganesha31
Enthusiast
Enthusiast
Jump to solution

Thanks for the reply! We use Vmware version 6. I remember reading that Version 6 doesn't support APIs to pull this data. Is this true? If not, can you please share the API link that I can read through to get this done through APIs instead of PowerCLI cmdlets. Thanks in advance!

0 Kudos
LucD
Leadership
Leadership
Jump to solution

I don't know where you heard that, but afaik you can use the API methods and properties.

Since your script is accessing multiple properties from different objects, you will have to look at the API Reference to find the corresponding properties.


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

0 Kudos
ganesha31
Enthusiast
Enthusiast
Jump to solution

Okay. Thank you! Will give it a read! Thank you once again for all the help! Really Appreciate!

0 Kudos
ganesha31
Enthusiast
Enthusiast
Jump to solution

I just realized that we have few 5.5 vCenters and I tried and I did hit the roadblock for the vCenter version 5.5. When I try to get the cluster details, I get the following message.

{"name":"com.vmware.vapi.rest.httpNotFound","localizableMessages":[{"defaultMessage":"Not found.","id":"com.vmware.vapi.rest.httpNotFound"}],"majorErrorCode":404}

The same thing worked for another vCenter, which I believe is v6.

Request : https://' + svCenterName + '/rest/vcenter/cluster'

Can you please let me know if there is anything that I'm missing here?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Yes, 5.5 doesn't have those REST API.


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

0 Kudos
ganesha31
Enthusiast
Enthusiast
Jump to solution

okay got it. I got mixed up with the versions earlier.. My bad.. Can you help me on how to use the Get-View ExtensionData to speed up the process?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

I'm wondering why you were using a REST API.

Which properties do you want to retrieve via the API?


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

0 Kudos
ganesha31
Enthusiast
Enthusiast
Jump to solution

We have around 15K VMs across different vCenters. We need to pull the Cluster, Host, VM, CPU, SocketsPerCore, MemGB, PowerStatus, HyperThread. (Have shared my script earlier in this mail thread). Using the PowerCLI cmdlets takes hours to pull this data and when I asked on how to speed up this process, you have suggested to use the APIs.

So, when I tried to use the APIs I have hit the roadblock as few vCenters are 5.5 version.

Now, I want to go back to PowerCLI cmdlets to pull this data but want to speed up the process and not wait for hours to get this data.

Can you guide me on how to get this data pulled quickly?

Thanks in advance!

0 Kudos
LucD
Leadership
Leadership
Jump to solution

When I mentioned API I was referring to the SOAP API, not the REST API.

In any case, try the following

$sCluster = @{

    ViewType = 'ClusterComputeResource'

    Property = 'Name'

    PipelineVariable = 'cluster'

}

$sVMHost = @{

    ViewType = 'HostSystem'

    Property = 'Name','Runtime.PowerState','Summary.Hardware'

    PipelineVariable = 'esx'

}

$sVM = @{

    ViewType = 'VirtualMachine'

    Property = 'Name','Summary.Runtime.PowerState','Config.Hardware'

    PipelineVariable = 'vm'

    Filter = @{'Summary.Config.Template'='False'}

}

Get-View @sCluster |

ForEach-Object -Process {

    Get-View @sVMHost -SearchRoot $cluster.MoRef |

    ForEach-Object -Process {

        Get-View @sVM -SearchRoot $esx.MoRef  |

        ForEach-Object -Process {

            $vm | Select @{N='Cluster';E={$cluster.Name}},

                @{N='VMHost';E={$esx.Name}},

                @{N='HostState';E={$esx.RunTime.PowerState}},

                @{N='HostCPU';E={$esx.Summary.Hardware.NumCpuCores}},

                @{N='CPUType';E={$esx.Summary.Hardware.CpuModel}},

                @{N='MemoryMB';E={[math]::Round($esx.Summary.Hardware.MemorySize/1KB)}},

                @{N='HyperThread';E={-not ($esx.Summary.Hardware.NumCpuCores -eq $esx.Summary.Hardware.NumCpuThreads)}},

                @{N='VM';E={$vm.Name}},

                @{N='VMState';E={$vm.Summary.Runtime.PowerState}},

                @{N='VMSockets';E={$vm.Config.Hardware.NumCpu/$vm.Config.Hardware.NumCoresPerSocket}},

                @{N='VMCoresPerSocket';E={$vm.Config.Hardware.NumCoresPerSocket}},

                @{N='VMLogicalCPUs';E={$vm.Config.Hardware.NumCpu}},

                @{N='VMTotalMemoryGB';E={$vm.Config.Hardware.MemoryMB/1KB}}

        }

    }

}


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

ganesha31
Enthusiast
Enthusiast
Jump to solution

Thank you so much! It works fine. I added up the code to export to Excel as well.

The value that is returned for MemorySize is in Bytes and as we are dividing it by 1024 the value is in KB. So, changed the label to MemoryKB instead of MB.

@{N='MemoryKB';E={[math]::Round($esx.Summary.Hardware.MemorySize/1KB)}},

0 Kudos