Mastering PowerCLI: Using Get-VM to work with virtual machines

Using PowerCLI to manage your VMware virtual machines can make administration a lot easier. In this tutorial, we go over one of the most important cmdlets.

There's a lot to learn if you're just starting to use PowerCLI to administer your VMware environment. Here, we take a look at one of the most common and important cmdlets.

In my last article, I introduced you to PowerCLI and hopefully whet your appetite for more of the same. Today, we're going to go talk about one of the most important cmdlets in the toolkit: Get-VM. PowerShell has a great built-in help system, so let's use that to show an overview of what Get-VM does. If you want to follow along, open PowerCLI from your start menu as you can see in this screenshot:

In the PowerCLI window, I'm going to pull out just the Synopsis field from the help file.

(Editor's note: To make it easier for you to follow along with the code, we have extracted the code and put it in a txt file, which you can access here. It's broken down into four sections, so you know which code the author is writing about.

Note that "PS >" indicates the shell prompt, and the text that immediately follows is what I typed. Everything else is output from a previously typed command.)

Get-VM, like all "get-cmdlets," is used to retrieve one or more objects. The most common thing you can do with these objects is to simply display them on the console. In other words, create a report. I showed you in the last article what happens when you run Get-VM by itself, provided you've created a connection to your ESX or vCenter server with the Connect-VIServer cmdlet. You are shown a table with four columns with information about all of your virtual machines: Name, PowerState, Num CPUs, and Memory (MB). Well, guess what? There is even more information behind the scenes. Let's take a look at one of my virtual machines (see Excerpt 2).

I want you to note several things:


  1. Get-VM has a Name parameter, to which you can supply one or more virtual machine names (or wildcards) to select only those objects. It's a positional parameter, and its position is zero, so that means you can actually leave off the text "-name" and PowerShell will figure out what you mean.


  2. I'm using the Format-List cmdlet so that the properties are displayed vertically. But in this case, I told it to display all properties by providing an asterisk wildcard. This way we get a nice screenful of stuff, not just the four properties which are shown by default. (Note: If you see fewer properties than I am, make sure you are running the latest version of PowerCLI. The version released as of this writing is 4.0 U1, but it does work against older VI environments.)


  3. Everything to the left of the colons is the name of a property. Everything on the right of the colons is the value of the preceding property.


  4. When you see that the value of a property is contained within curly braces, you are looking at an array of multiple values. In other words, your virtual machines can have multiple floppy drives, CD drives, hard disks, network adapters, and so on.

Understanding PowerShell properties
Some of the properties, such as PowerState, Description, or Name are self-explanatory if you know your way around the vSphere client, so I won't go over them. Then there are several properties whose names end in "Id" such as "HostId." These are reference fields which contain a link to another type of object. There are also a few fields dedicated to some of the more advanced VMware features such as HARestartPriority, HAIsolationResponse, and DrsAutomationLevel. I'm not to go into detail about these right now, but it suffices to say that they map to similarly named fields in the vSphere client.

There is one field in particular, however, to which I want to give some extra attention, and that's the Guest property. At first glance, the value of the Guest property is VMware.VimAutomation.Client20.VMGuestImpl. In fact, this is the full ".NET class name" of the object sitting in that property.

Say what?

OK, Let me say that a different way. Everything in PowerShell is an object. Objects have members, and members include properties and methods (and other things besides). In case you haven't been introduced to object-oriented programming before, let me get you started with a couple of definitions:

Property - An attribute of an object. Properties have values associated with them. For example, a car object has a "body color" property, and the value of this property could be "white".

Method – An action which may be taken upon an object. Methods may be invoked to effect the desired action. For example, a car object has an "accelerate" method. Invoking this method would cause the car to move forward.

In PowerShell (and PowerCLI), the values of the properties of an object are themselves: objects. Most often, properties are primitives, which is to say that they are really simple objects like a string (e.g. "vm1"), or an integer (e.g. 32). With me so far?

In the case of the Guest property, instead of a simple string, we are dealing with a VMGuestImpl object, (taking just the last portion of the object name given above). Let's take a look at it using the Get-Member cmdlet. Get-Member comes with PowerShell, not PowerCLI, and it's great for examining objects as you can see in Excerpt 3.

In the first line above, I'm assigning the virtual machine object, which is returned by Get-VM, to a variable called "vm." Doing so makes the next line of code a bit easier to read, and plus it makes subsequent operations on the same object happen more quickly because you are caching it in memory.

In the second line of code, I use a dot followed by the name of the property I want to examine. Then, I "pipe" that property to the Get-Member cmdlet. I'm also telling the Get-Member cmdlet that I only want to see properties. That does a good job of simplifying the output slightly for this example.

The table of output from Get-Member has three columns: Name, MemberType, and Definition. The first two are fairly straightforward. The third; definition, is a bit more complex. The reason I'm showing you this table is to explain the relationship between properties and objects in PowerShell. The first portion of the definition shows you what type of object that a property holds. As you can see, several are "System.String." and that just means a series of characters. Others have longer names which start with "VMware," and you can assume that these "go deeper" (just like this VMGuestImpl object!) and have even more information contained within.

I'll end this column by showing you how to display these properties and their values (See fourth excerpt). Be sure to tune in next time when I'll be teaching you how to edit a virtual machine's settings using the Set-VM cmdlet!


Hal Rottenberg is a Microsoft PowerShell MVP and VMware vExpert living in Woodstock, Georgia. He is well-known in system administrator circles for co-hosting the PowerScripting Podcast and heading up the PowerShellCommunity organization. He is also the author of a book titled "Managing VMware Infrastructure with PowerShell: TFM" published by SAPIEN Press in 2009.

Dig Deeper on Scripting administrative tasks