Home > Blogs > VMware PowerCLI Blog > Monthly Archives: March 2009

Monthly Archives: March 2009

Travel back in time with Veeam Reporter

Veeam released a rather interesting set of PowerShell cmdlets called the Veeam PowerShell Extensions that provide a few cmdlets that are very similar to some cmdlets you get with VI Toolkit. For example, they have their own versions of Get-VM and Get-VMHost which return information about VMs and ESX hosts inside of VI.

The most interesting feature they have is the _Set-VRCurrentDate cmdlet, which allows you to pick a date for which you would like to see information. In other words, when you first connect, the data you see is current, but if you want to see data from a month ago, all you do is set the date to a month ago, and their _Get-VM cmdlet will give you all VM information from a month ago.

Lately a lot of people have been building reporting tools on top of VI Toolkit, such as Alan Renouf’s amazing Visio generator. It looks like it should be fairly easy to hook these reports up to Veeam’s database so that not only could you get a Visio diagram of your VI today, you could also get a diagram of what it looked like a month ago and compare the two. This looks like an interesting tool worth checking out.

Why is my code so slow?

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.

In other words, Slow takes more than 200 times longer to execute than Fast does. What could possibly explain this dramatic difference in speed?

We’ll return to that after we take a look at the PowerShell signature for the Get-HardDisk cmdlet.

Get-HardDisk [[-VM] <VirtualMachine[]>]
 [[-Template] <Template[]>] [[-Snapshot] <Snapshot[]>]
 [-Server <VIServer[]>] [<CommonParameters>]

If you’re versed in PowerShell you know that this means that the –VM argument to Get-HardDisk requires a VirtualMachine object, which is the type of object that Get-VM outputs.

You may notice, though that the second code sample above uses the VM’s Name property, which is a string as the –VM argument. How is it possible for something like Get-HardDisk -VM "myVM" to work at all? After all, “myVM” is a string, not a VirtualMachine, so shouldn’t this fail?

The reason this works is because VI Toolkit takes advantage of a feature of PowerShell that lets you transform the arguments you receive on the command line. This is the basis of what we call the VI Toolkit’s “Object By Name” feature: If you specify a string where an object should be, VI Toolkit works behind the scenes to replace this string with the object that the string represents.

Inevitably this lookup has a cost, the question is how much is that cost? This brings us to a rather unfortunate property of VI Toolkit, which is that when you get a VM, all filtering is done on the client side. On one hand this is good because it allows us to support wildcards and case-insensitivity. However there is one very unfortunate consequence, which is that it takes just as long to load one VM as it takes to load all of them (more on how we are improving this below). This is the basic reason that the second example is so slow: every time Get-HardDisk is called, VI Toolkit looks up that one machine object behind the scenes.

Computer sciencey-types have some fancy terminology called “Big O Notation” that helps the discussion here. If you don’t know Big O Notation, don’t worry there’s no quiz at the end. But basically Big O Notation lets us understand why some approaches are fast and some approaches are slow. The first code sample is “order of N” or O(N), where N is the number of VMs on the system. This is because you need to load N many VM objects into memory, using Get-VM, then feed the objects into Get-HardDisk, which is pretty quick. The second code sample is “order of N squared” or O(N2) because for each of those N VMs you load using Get-VM you turn around and load the exact same N VMs when Get-HardDisk goes through all VMs looking for the one with that particular name. Since you load those N objects N many times, you end up with O(N2). The larger N is, the more dramatic the differences in execution time. In my case I had 465 VMs and the code took about 230 times longer, which sounds reasonable enough (this is not a very exact science). If I had 1000 VMs you could expect that it would take something closer to 1000 times longer, for 2000 VMs it would be closer to 2000 times longer. You get the idea: You don’t want to do this sort of stuff if you’ve got a big environment.

As we see from this example, there are some fairly subtle differences that can cause your code to be really slow. How do you avoid these landmines in your code? Use these best practices to maximize your code’s performance:

  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.

One thing you may be happy to hear is that in the future we will be optimizing the case of looking up a single VM by name and it will be a lot faster. This will be done using a technique similar to the one used by Get-VMFast. You should note though that even with this faster lookup of single VMs, the second code sample above is still O(N2), but the code will still be a lot faster because those second lookups are so much faster. The computer sciencey-types would say that we have a much smaller constant factor. Still, eventually that factor of N takes over and things will get slow again. To put it another way, the landmine is still there but it will be small enough that most people probably won’t manage to step on it. But, if you need maximum performance out of your code, you need to use suggestions 1 and 2 as outlined above.

VI Toolkit Demos at VMworld Europe 2009 (Part 1 of 2: Network Monitoring)

We did two live demos as part of VI Toolkit’s breakout session at VMworld Europe 2009. This post is about the first demo which featured some network configuration monitoring and Carter’s cell phone beeping loudly when he received the alert emails…

So, you’re a VI system administrator and you have a policy that no VM can be simultaneously connected to the Intranet and the DMZ. With all the configuration changes going on, it would be nice if a script could monitor the network and drop you an email when some change breaks the policy.

With VI Toolkit stuff like this is pretty easy. How about getting all VMs and then examining each one’s network configuration? Sounds about right but it could be a bit slow if you have a large number of VMs. Let’s tweak it a bit by first looking at the Virtual Center’s even log. Filter only events which show that a VM’s network was reconfigured. Then go check only those VMs.

You want a script which runs the check repeatedly until you stop it. So, each time, it needs to look only at the events, created since the last check. And with PowerShell’s native access to .Net library, sending email is a piece of cake.

Finally, here’s the script itself (you need to be connected before you run it):

Monitoring ESX hardware with PowerShell

Did you ever wonder where all the info under Health Status in VI Client comes from?


It turns out that your ESX server has a server built in to it that provides this information via a management standard called CIM, which is owned and promoted by the DMTF standards body. A lot of the information you can find in this CIM interface is also available through the VI API, but there is quite a bit that can only be found through CIM, most importantly, health status of the hardware hosting ESX. In this post we’ll go through some of the information that’s available and samples of getting at it.

When Microsoft released PowerShell v2 CTP3, they added some cmdlets that can access CIM. The implementation is very raw right now, for example the cmdlets don’t even have help. Also, getting this stuff working is a bit of a production. You need PowerShell v2 CTP3 and WinRM 2.0 CTP3. This latest version of WinRM only supports Windows 2008, Windows Vista and Windows Mojave, so you XP users are out of luck. You’ll also need to enable basic authentication.

Once you’ve got it set up, I’ve written a pretty easy advanced function that lets you take advantage of it.

This function makes it pretty easy to access ESX hardware information, as you’ll see below. All you need to do is connect to your ESX server, then run the function, supplying it a class name that you care about. You can find a complete list of classes in our documentation. Note that not all classes are available on all systems. As far as I know the only way to know for sure is to try it for yourself.

Here’s a sample script that puts this through its paces, and some screenshots of the results after I ran it against one of my ESX systems.

Let’s see it in action. First let’s check out all the numeric sensors that are on my system. The exact list of numeric sensors will vary from system to system, but common ones include fan speeds and temperature readings, as on my system.


It’s a little strange that my fan speeds are far below their normal minimum values, yet that doesn’t seem to be causing problems, the ambient temperature is far below the maximum value. Note that for some reason all the values here are multiplied by 100, and that the temperature are in Celsius (just like those snobby Europeans use). You can see all the possible values either by running the code or referring to this specific class in the documentation.

Next, let’s look at some actual health status, first taking on CPU.


So what the heck does HealthState 5 mean? Well I’m not sure, but one thing I am sure of is that the word uninscrutable is not in the DMTF’s collective vocabulary. To figure out what this mysterious 5 means, we again have to consult our trusty documentation. If we look at the HealthState entry we see rows for ValueMap and Values. All we have to do is correlate the value of 5 with the text in Values. Doing that we learn that HealthState 5 means “OK”.

This is true in general when you’re looking at health states: 5 always mean that the thing is OK. The value of 0 means that the state is unknown. This is not necessarily a problem, for example it may mean that the device in question is turned off. If you expect the thing to be on and useful, a value of 0 is a bad thing, otherwise it may not be worth worrying about. Any of the other values means you’ve got some sort of hardware problem that needs attention.

Now let’s look at my power supplies:


In this case I’ve got one power supply with health state 5 (OK) and one with state 0 (Unknown). Chances are my second power supply is not plugged in. (It’s in a datacenter far far away so I can’t check it.) In any event I’m not too worried about this Unknown value.

Let’s take a look at the health state of my storage. My ESX server has 3 disks, and as usual 5 is the best health state of all.


This next one shows that CIM can also be used to see data that’s also available through VI API. In this case I get the total amount of storage on this ESX system, which happens to be the same as the amount of storage in my local datastore.sample5

Finally, I take a look at some network stuff. In this case I look at Ethernet ports. Ethernet ports don’t have a health status, that’s reserved for the cards. But I can see the link status using CIM. In this case, vmnic0 and vmnic1 are plugged in while vmnic2 and vmnic3 are not.


I hope you found this useful, there’s a lot of really great information waiting to be discovered through the CIM interface.

Create some amazing reports with the PowerGUI PowerPack

Kirk Munro and crew have been working hard on a new VMware PowerGUI PowerPack

The best new feature is the ability to draw diagrams of your VI environment, like the one here:


To get some diagram goodness, you need to have vCenter, VI Toolkit 1.5, the latest PowerGUI and PowerPack, and Visio 2007. Once you’ve got all that in order you can create some great diagrams of your virtual environment. I saw a demo of this stuff at VMworld Europe courtesy of Scott Herold and it was really amazing. Note that to generate reports you need to select either a cluster or a datacenter within PowerGUI.

I also wanted to say that Kirk, Scott and all the others at Quest that they’re doing a wonderful job and I’m really looking forward to seeing all this stuff come together when the Virtualization EcoShell launches later this month.

Do you really need automation?

It’s a trick question, the answer is yes. But where do you need it?

We’re running a poll over on the VI Toolkit Community where you can vote for the VMware product most in need of automation in the form of PowerShell cmdlets (registration required to participate). Let us know where you need automation the most.

VI Toolkit Quick Reference Guide

If you haven’t seen it yet, Alan Renouf has put together a great VI Toolkit Quick Reference Guide, it covers all the basics of managing ESX and vCenter with VI Toolkit.