Receving cluster name for vms fast.


If there is built in mechanism of getting the clustername for VM then i don’t know it 😉 that’s why i wrote this idea down. Well it does the trick, that’s what counts for me. So here is the idea that i drew in paint 😉
drawing

So we will make hashtables for VMs to VMHosts, then VMHosts to cluster names, and then get the cluster name for vm by choosing the correct hash.
I don’t know if i am explaining that clearly, so please don’t hesitate to write comments.

$Clusters=get-view -ViewType ClusterComputeResource -Property Name,Host
$vms=Get-View -ViewType VirtualMachine -Property Name,Summary.Runtime.Host
$VMs|%{ [hashtable]$VmsToHostHash+=@{ $_.Name.ToString() = $_.Summary.Runtime.Host.ToString()}}
foreach ($cluster in $clusters ) {$cluster.Host | % { [hashtable]$HostToClusterHash+= @{$_.ToString()=$cluster.Name}} }

We receive first clusters objects. We will use their Name property and Hosts that are inside. Then We get the virtualmachines objects with name and host on which it is living information. After this we are building the hashtables that are mentioned earlier.

We could just simply use it by calling:

$HostToClusterHash[$vmsToHostHash['VMNameGoesHere']]

That can be all, but we can write little simple function to query that as well. Of course that could be built in proper manner, with some error handling and getting all kinds of objects and not string only.

Function Get-ClusterNameFromVMName{
param(
[string[]]$VMName,
[hashtable]$VmsToHostHash,
[hashtable]$HostToClusterHash
)
return $HostToClusterHash[$vmsToHostHash[$VMname]]
}

We could then get cluster name by typing:
Get-ClusterNameFromVM -VMName ‘SomeVMname’ -VmsToHostHash $VmsToHostHash -HostToClusterHash $HostToClusterHash

Basically the first part that is collecting needed data should run pretty fast, for example on VC with ~2000 vms it completes within 4.5 second.
The part to get actually the cluster name is instant.

While getting data we also prepared the $vms variable that holds vms objects so if we would do now:
measure-command {foreach ($vm in $vms){ $vm | select name, @{n=’CLname’;e={$HostToClusterHash[$vmsToHostHash[$($vm.name)]]}} } }

we can expect below results:
Seconds : 0
Milliseconds : 351

Output would be very simple:
VMName ClusterName

This is just an idea, you can try to use this approach whenever you need to quickly get just cluster name for VM. What is worth adding 😉 This is not perfect solution, you have to remember that hashtables can refuse to add vm if you have vms with duplicate names. The main reason for me to build this is that i will be doing some examples for plvmug that will be querying a lot vms in regards of their clusters. This script only watches cluster, not single vmhosts, so please have this in mind as well.

[update]
As per Robert van den Nieuwendijk comment. Actually there is also more elegant way of getting the cluster name for vm. Below is example from Robert:

Get-VM | Select-Object -Property Name,@{Name=’Cluster’;Expression={$_.VMHost.Parent}}

#And with new-viproperty approach

New-VIProperty -ObjectType VirtualMachine -Name Cluster -Value {$Args[0].VMHost.Parent} -Force
Get-VM | Select-Object -Property Name,Cluste

Advertisements

3 thoughts on “Receving cluster name for vms fast.

  1. The Cluster object is in the Parent property of a VMHost object. The VMHost object is in the VMHost property of a VirtualMachine object. So, to retrieve the cluster names of your virtual machines, you can use the following code:
    Get-VM | Select-Object -Property Name,@{Name=’Cluster’;Expression={$_.VMHost.Parent}}

    If you use the New-VIProperty cmdlet to add a Cluster property to a VirtualMachine object, the code will even be more simple:
    New-VIProperty -ObjectType VirtualMachine -Name Cluster -Value {$Args[0].VMHost.Parent} -Force
    Get-VM | Select-Object -Property Name,Cluster

    • Hi Robert, yeah did not think about that, that’s an excellent comment. Of course this is easier way of doing it. I did it because i needed VM/cluster info fast. That’s the only reason why i wrote this one. In small inventory your way of doing it is really neat, and fast. It gets slower on bigger inventory though. In my small lab i could use this way and there is no problem with speed. Here are my results for bigger inventory:
      New-VIProperty -ObjectType VirtualMachine -Name Cluster -Value {$Args[0].VMHost.Parent} -Force
      measure-command { $rez=Get-VM | Select-Object -Property Name,Cluster }
      Minutes : 1
      Seconds : 4
      Milliseconds : 572

      Then i used the other example :
      Measure-Command {$result=get-vm |select name ,@{n=’CL’;e={$_.vmhost.parent.name}} }
      Minutes : 1
      Seconds : 4
      Milliseconds : 363

      Then with my approach:
      measure-command{
      $Clusters=get-view -ViewType ClusterComputeResource -Property Name,Host
      $vms=Get-View -ViewType VirtualMachine -Property Name,Summary.Runtime.Host
      $VMs|%{ [hashtable]$VmsToHostHash+=@{ $_.Name.ToString() = $_.Summary.Runtime.Host.ToString()}}
      foreach ($cluster in $clusters ) {$cluster.Host | % { [hashtable]$HostToClusterHash+= @{$_.ToString()=$cluster.Name}} }
      $res=foreach ($vm in $vms){ $vm | select name, @{n=’CLname’;e={$HostToClusterHash[$vmsToHostHash[$($vm.name)]]}} }
      }

      Minutes : 0
      Seconds : 7
      Milliseconds : 35

      I will add your example to my post, as it is really nice.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s