Go Go PowerShell Speed Racer! – Speeding up PowerShell scripts.

From the VI Toolkit blog.

Can you spot the difference between this code:

1: foreach ($vm in (get-vm)) {

2: $disks = Get-HardDisk -vm $vm

3: foreach ($disk in $disks) {

4:  Write-Host $disk.CapacityKB

5: }

6: }

And this code:

1: foreach ($vm in (get-vm)) {

2: $disks = Get-HardDisk -vm $vm.name

3: foreach ($disk in $disks) {

4:  Write-Host $disk.CapacityKB

5: }

6: }

This is not quite a trick question, the only difference is that one uses $vm and one uses $vm.name in the second line. Both of these are valid and produce the same results. However, there’s a really important difference between them. I timed these code samples in my environment and here are the results:

    * Code sample 1 (aka Fast): 13.44 seconds.
    * Code sample 2 (aka Slow): 3178.55 seconds.

  1. Try to load as many objects as possible into arrays beforehand. Once you’ve got them loaded you can use them as arguments to multiple calls without having to resort to potentially expensive lookups every time.
  2. Just like in sample 1 above, when you’ve loaded objects, use the objects directly rather than using their names. This is usually not hard as our cmdlets are designed to take object first-and-foremost, and names are supported just as a convenience.
  3. If you absolutely need to load a single VM object by name, load it using the Get-VMFast function below. While this approach can certainly help, it’s not nearly as good as using the other two techniques mentioned above.