Why New-VIProperty Matters!

As you may have noticed, PowerCLI 4.1 has some cool new features for accessing the underlying SDK objects from within the PowerCLI objects. Before PowerCLI 4.1 your only door to the SDK objects was using the Get-View cmdlet, but you can use the .ExtensionData property now. This makes it much easier and requires less code to access the SDK objects.

Besides the .ExtensionData property there’s a new cmdlet called New-VIProperty which enables you to define custom properties for PowerCLI objects. You also might want to have a look at this article from Luc Dekens.

Since I have to script against large environments mostly, speed is my concern. So I ‘m interested in the performance benefit’s from using these new methods and I’m trying to demonstrate the performance gain acquired by using these new methods over the Get-View cmdlet.

1 Performance test using the 3 different methods

For this test I’m going to retrieve the VMware Tools version from a random virtual machine in my environment. To have a more reliable result, I’m going to do the same operation several times and calculate the average processing time. Therefore I’ve constructed a for loop to execute the code 100 times and measure the time it takes to retrieve the property. Then I calculate the average execution time.

1.1 Using the Pre-PowerCLI 4.1 Get-View method

This test uses the Get-View cmdlet, as we’re used to before PowerCLI 4.1, to retrieve the underlying SDK object of the virtual machine to report the VMware Tools version, which is stored in the .config.tools.toolsVersion property.

The code:

$samples=@()
For ($i=0;$i –lt 100;$i++) {
$vm = Get-VM | Get-Random
$(measure-command {$vm | Get-View | %{$_.config.tools.toolsVersion}}).TotalMilliseconds | Tee-Object -Variable sample
$samples += $sample
}
$samples | measure-object -Average

The result:

Average execution time is 224.93 milliseconds

1.2 Using the .ExtensionData property method

This test uses the new PowerCLI 4.1 .ExtensionData property to retrieve the VMware Tools version.

The code:

$samples=@()
For ($i=0;$i –lt 100;$i++) {
$vm = Get-VM | Get-Random
$(measure-command {$vm | %{$_.ExtensionData.config.tools.toolsVersion}}).TotalMilliseconds | Tee-Object -Variable sample
$samples += $sample
}
$samples | measure-object -Average

The result:

Average execution time is 223.58 milliseconds

1.3 Using the New-VIProperty method

Now let’s use the New-VIProperty cmdlet to extend the virtual machine’s PowerCLI object with a toolsVersion property.

The code:

$samples=@()
New-VIProperty -Name toolsVersion -ObjectType VirtualMachine -ValueFromExtensionProperty 'config.tools.toolsVersion'
For ($i=0;$i –lt 100;$i++) {
$vm = Get-VM | Get-Random
$(measure-command {$vm    | %{$_.toolsVersion}}).TotalMilliseconds | Tee-Object -Variable sample
$samples += $sample
}
Remove-VIProperty -Name toolsVersion -ObjectType VirtualMachine
$samples | measure-object -Average

The result:

Average execution time is 0.82 milliseconds

As you can see the .ExtensionData property isn’t faster than using the Get-View cmdlet. This is because the .ExtensionData property will fetch the SDK object as soon as the property is requested like the Get-View cmdlet. This behavior can be visualized by altering the code a bit and moving the Get-VM part outside of the for-loop.

The code:

$samples=@()
$vm = Get-VM | Get-Random
For ($i=0;$i –lt 5;$i++) {
$(measure-command {$vm | %{$_.ExtensionData.config.tools.toolsVersion}}).TotalMilliseconds | Tee-Object -Variable sample
$samples += $sample
}
$samples | measure-object -Average

The result:

As you can see, retrieving the toolsVersion property the first time took much longer than the consecutive times.

The New-VIProperty example in the test is much faster, although not quite fair, because the fetching of the toolsVersion property is done while retrieving the VM with the Get-VM cmdlet and this overhead isn’t measured.

2 Performance penalty for using New-VIProperty

Let’s have a look at the performance penalty for defining an extra property using the New-VIProperty cmdlet

2.1 Using the default Get-VM cmdlet to retrieve all vms

The code:

$samples=@()
For ($i=0;$i –lt 100;$i++) {
$(measure-command {Get-VM}).TotalMilliseconds | Tee-Object -Variable sample
$samples += $sample
}
$samples | measure-object -Average

The result:

Average execution time is 1074.30 milliseconds

2.2 Using the Get-VM cmdlet with an custom property defined by the New-VIProperty cmdlet

The code:

$samples=@()
New-VIProperty -Name toolsVersion -ObjectType VirtualMachine -ValueFromExtensionProperty 'config.tools.toolsVersion'
For ($i=0;$i –lt 100;$i++) {
$(measure-command {Get-VM}).TotalMilliseconds | Tee-Object -Variable sample
$samples += $sample
}
Remove-VIProperty -Name toolsVersion -ObjectType VirtualMachine
$samples | measure-object -Average

The result:

Average execution time is 1187.77 milliseconds

I’ve ran the above mentioned test multiple times and the resulting penalty for using the New-VIProperty cmdlet is between 10-20%, but this can be neglected compared to the penalty of having to use an extra Get-View in your script. The new possibilities in PowerCLI 4.1 are looking promising, but the test wasn’t a real life test.

3 Report performance test

To test the performance of the new methods in a more production like test, I’m going to create a small report on my vms and their VMware Tools version.

3.1 The Pre-PowerCLI 4.1 code using Get-View:

The code:

$samples=@()
For ($i=0;$i –lt 100;$i++) {
$(measure-command {
$report=@()
$report += Get-VM | Get-View | Select-Object Name,@{Name="ToolsVersion";Expression={$_.config.tools.toolsVersion}}
$report
}).TotalSeconds | Tee-Object -Variable sample
$samples += $sample
}
$samples | measure-object –Average

The result:

Average execution time is 11.83 seconds

3.2 Using the .ExtensionData property instead of Get-View:

The code:

$samples=@()
For ($i=0;$i –lt 100;$i++) {
$(measure-command {
$report=@()
$report += Get-VM | Select-Object Name,@{Name="ToolsVersion";Expression={$_.extensiondata.config.tools.toolsVersion}}
$report
}).TotalSeconds | Tee-Object -Variable sample
$samples += $sample
}
$samples | measure-object –Average

The result:

Average execution time is 11.82 seconds

3.3 The PowerCLI 4.1 code using New-VIProperty:

The code:

$samples=@()
For ($i=0;$i –lt 100;$i++) {
$(measure-command {
$report=@()
New-VIProperty -Name toolsVersion -ObjectType VirtualMachine -ValueFromExtensionProperty 'config.tools.toolsVersion'
$report += Get-VM | Select-Object Name, toolsVersion
$report
}).TotalSeconds | Tee-Object -Variable sample
$samples += $sample
Remove-VIProperty -Name toolsVersion -ObjectType VirtualMachine
}
$samples | measure-object -Average

The result:

Average execution time is 1.14 seconds

The new PowerCLI 4.1 code is 10 times faster!.

Conclusion

I’ve done several tests to measure the performance benefit from using the .ExtensionData property and the new PowerCLI 4.1 New-VIProperty cmdlet in contrast to using the Get-View cmdlet. As you can see there’s no benefit using the .ExtensionData property instead of using the Get-View cmdlet, but it can make your code less complex if you need a property from the underlying SDK object occasionally.

The New-VIProperty cmdlet on the other hand, really does improve performance. In the test that I’ve conducted the New-VIProperty feature makes the script run 10 times faster, so you better get used to using this cool new feature.

Related posts:

  1. PowerCLI 4.0 Update 1- Another leap forward Tweet Last week VMware released PowerCLI 4.0 Update1. According to the PowerCLI blog this new version contains over 60 new cmdlets as well as greatly improved performance. One great thing...
  2. Collect VMware ESX Host PCI Device Information Tweet Whenever you need to install a new box with ESX, there’s the struggle with matching physical ports to VMware devices. Which network adapter becomes vmnic0?, Which hostbus adapter becomes...
  3. $Null or Nothing? Tweet When looking at a lot of PowerCLI scripts available I noticed that people tend to forget to validate their output. For example let’s look at the following piece of...
  4. PowerCLI: Reset CPU and Memory Limits Tweet Today I noticed a memory limit on a vm. After investigating my environment using the vEcoShell and the Community PowerPack, I found more vms with memory limits set. It turned out...
  5. PowerCLI 4.1 namespace changes Tweet Output type changes in PowerCLI 4.1In PowerCLI 4.1 VMware changed the namespaces of the output types. According to VMware, this was done to improve the internal structure and enable...

4 Comments on “Why New-VIProperty Matters!”

  1. #1 Sammy Bogaert
    on Sep 20th, 2010 at 3:44 pm

    An even faster way of doing this with the help of Get-View is to fetch only the properties you need. This speeds up things massively!
    I rarely use the Get-VM, Get-Cluster, … cmdlets these days and use Get-View where possible with these 2 additional parameters:
    - ViewType: What type of objects to fetch
    - Property: A list of properties to fetch (these can be nested)
    - Filter: If you want to reduce your results. This filter will be processed server-side and is much faster than doing if afterwards with a foreach loop.

    The ‘Report Performance Test’ code would look like this:

    3.4 Get-View with Property and ViewType arguments

    $samples=@()
    For ($i=0;$i –lt 100;$i++) {
    $(measure-command {
    $report=@()
    $report += Get-VM | Select-Object Name,@{Name=”ToolsVersion”;Expression={$_.extensiondata.config.tools.toolsVersion}}
    $report
    }).TotalSeconds | Tee-Object -Variable sample
    $samples += $sample
    }
    $samples | measure-object –Average

    To can offcourse be combined with the New-VIProperty:

    3.5 Get-View with Property and ViewType arguments combined with New-VIProperty.

    $samples=@()
    For ($i=0;$i –lt 100;$i++) {
    $(measure-command {
    $report=@()
    New-VIProperty -Name toolsVersion -ObjectType VirtualMachine -ValueFromExtensionProperty ‘config.tools.toolsVersion’
    $report += Get-View -ViewType “VirtualMachine” -Property Name, config.tools.toolsVersion | Select-Object Name, toolsVersion
    $report
    }).TotalSeconds | Tee-Object -Variable sample
    $samples += $sample
    Remove-VIProperty -Name toolsVersion -ObjectType VirtualMachine
    }
    $samples | measure-object -Average

    I ran the report performance test in my environment:

    3.1: 22.94 seconds
    3.2: 22.89 seconds
    3.3: 4.24 seconds
    3.4: 0.81 seconds
    3.5: 0.78 seconds

    That’s another 5 times faster compared to your new code and a zillion times faster than the original code.

    Take a look at my blogpost for some more examples on this subject: http://boerlowie.wordpress.com/2010/08/09/how-many-powered-on-vms-are-running-on-my-host/

    grtz,
    Sammy Bogaert

  2. #2 Arnim van Lieshout
    on Sep 20th, 2010 at 8:01 pm

    Of course using only Get-view is much faster, especially when using the parameters you mentioned, but I wasn’t looking for the fastest code. The essence of the article was to show the performance improvement of using the New-VIProperty cmdlet. Remember, the fastest code isn’t always the best code.
    The PowerCLI objects and cmdlets were designed to hide the complexity of the full SDK objects. Using Get-View makes the code more complex and difficult to read. Structure and readability is equally important when designing code.
    Your example in 3.5 is not correct. The New-VIProperty cmdlet doesn’t affect the SDK objects, but only the PowerCLI objects. So there is no toolsversion property created and your report will be empty. ;-)

    The code should look something like

    $samples=@()
    For ($i=0;$i –lt 100;$i++) {
        $(measure-command {
            $report=@()
            $report += Get-View -ViewType “VirtualMachine” -Property Name,
                config.tools.toolsVersion | Select-Object Name,
                @{Name=”toolsVersion”;Expression={$_.config.tools.toolsVersion}}
            $report
        }).TotalSeconds | Tee-Object -Variable sample
        $samples += $sample
    }
    $samples | measure-object -Average
    
  3. #3 Sammy Bogaert
    on Sep 20th, 2010 at 8:18 pm

    Arnim,

    Correct, i guess i made a mistake somewhere with the copy-paste operations :-)

    I agree that Get-View adds some complexity, but when managing large environments, it’s sometimes the ‘better’ way to run cmdlets because of the giant speed wins. Some clients have 1000+ VM’s and running script on those environments make you squeeze out every cmdlet :-)

  4. #4 Características avanzadas de la powerCLI | El Blog de Virtualizacion en español
    on Mar 31st, 2011 at 8:17 am

    [...] Why New-VIProperty Matters! de Arnim Van Lieshout ArrayArrayArrayArrayArrayArrayArrayArrayArray If you enjoyed this post, make sure you subscribe to my RSS feed! [...]

Leave a Comment