VMware
1 2 Previous Next 21 Replies Last post: Jun 18, 2008 6:09 AM by halr9000  

How To: Accessing the entire Virtual Infrastructure API from PowerShell. posted: Mar 15, 2008 4:02 PM

Click to view c_shanklin's profile Master 758 posts since
Dec 3, 2007
Hello everyone,

First I want to thank all of you for participating in our VI Toolkit (for Windows) (aka PowerShell toolkit) technology preview. I'm Carter Shanklin, I'm a product manager at VMware and one of my responsibilities is to make the PowerShell toolkit as good as possible. We rely on you to help us make our toolkit better, so if you have questions, suggestions or complaints be sure to pass them along.

If I were to summarize the design goal of the VI Toolkit (for Windows) it would be to make common tasks extremely simple, while making complicated tasks possible. For common tasks, we will provide over 100 cmdlets when the toolkit becomes generally available. As we improve the toolkit, this number will grow, as will the richness of the cmdlets we currently have.

By contrast, the VMware Virtual Infrastructure API contains 320 functions, and addins are available that can grow this number even higher. Obviously there will be parts of the API that will not be covered by 100 or so cmdlets. Even if we did deliver, say, 350 cmdlets, the VI API is so detailed, we feel that exposing all of this would make it difficult to ensure that common tasks are extremely simple. To deal with this challenge, we've adopted a layered approach.

Let's talk more about this layered approach. We view this sort of like peeling the onion; you only go as deep as you have to, and there a lot of stuff on the surface that doesn't require a deep understanding of Virtual Infrastructure. On the surface, we provide cmdlets, and the cmdlets provide an extremely simple means to automate your routine tasks. If you need to accomplish something not provided by the cmdlets, you can dig deeper and talk to the VI API directly.

The full power of the VI API is accessed using these cmdlets:

    1. find-entityview
    2. find-entityviews
    3. get-view
    4. get-views

These cmdlets allow you to load VI API managed objects (such as Virtual Machines, Datastores, Networks, etc.) into PowerShell. Once you've loaded a managed object into PowerShell, you can invoke any method the object supports. In this way, PowerShell becomes another language binding to our web services API, and you can program in PowerShell just as you would program in other languages.

Let's compare and contrast the cmdlet approach to the managed object approach:

This script shows how simple it is to power on a VM using the PowerShell cmdlets.

# Power on a virtual machine: cmdlet version.
# Connect to the ESX/VC server.
get-viserver -server <IP Address> -user <User> -password <Pass>
#
# Power on the VM.
get-vm <VMName> | start-vm
Compare this with the managed object approach:

# Power on a virtual machine: managed object version.
# First, connect to the ESX server.
get-viserver -server <IP Address> -user <User> -password <Pass>
#
# Build a filter to specify a specific virtual machine.
$nvc = new-object System.Collections.Specialized.NameValueCollection
$nvc.Add("name", "<VMName>")
#
# Find the virtual machine. $vm is the virtual machine managed object.
$vm = find-entityview -viewtype VirtualMachine -filter $nvc
#
# Power on the virtual machine.
$vm.PowerOnVM_Task($none)
If we ignore the steps required to connect, using the managed object approach grows the script from 1 line to 4 lines. A question you might ask is, "How do I know what objects to use, and what methods are available when I use them?" To answer this, we have to refer to the VI API documentation. This is the common set of documentation used by any language that talks to the VI API. In short, when we use the cmdlets mentioned above, accessing the VI API from PowerShell is not much different from accessing it in any other language.

Let's turn our attention to something more complicated. Specifically let's perform an operation that is not currently possible using the cmdlets provided by the toolkit. This example will show how to configure a virtual machine's startup properties. In ESX it is possible to specify the order in which virtual machines are booted, and how long to wait to boot the virtual machine. By default virtual machines are not started when ESX boots unless you change the default bootup policy. Obviously this is bad if you are trying to run critical services on ESX. This script will configure a virtual machine to boot first, 60 seconds after the system becomes available.

# Connect to the ESX server.
get-viserver -server <IP Address> -user <User> -password <Pass>
#
# Build a filter to specify a specific virtual machine.
$nvc = new-object System.Collections.Specialized.NameValueCollection
$nvc.Add("name", "<VM Name To Find>")
#
# Get the VM we want to reconfigure.
$vm = find-entityview -viewtype VirtualMachine -filter $nvc
#
# Get the HostSystem. If you're using Virtual Center, use a filter to
# select a particular host.
$hostSystem = find-entityview -viewtype HostSystem
$autoStartRef = $hostSystem.configManager.autoStartManager
$autoStartManager = get-view -MoRef $autoStartRef
#
# Configure the VM to start first, after 60 seconds. We do this by
# building a data object of type AutoStartPowerInfo.
$powerInfo = new-object VMware.Vim.VimProxy.AutoStartPowerInfo
$powerInfo.Key = $vm.MoRef
$powerInfo.StartOrder = 1
$powerInfo.StartDelay = 60
$powerInfo.StartAction = "powerOn"
$powerInfo.StopAction = "powerOff"
#
# Wrap the argument above in the variable used by reconfigureAutostart.
$config = new-object VMware.Vim.VimProxy.HostAutoStartManagerConfig
$config.PowerInfo = $powerInfo
#
# Perform the reconfiguration.
$autoStartManager.reconfigureAutostart($config)
As you can see, this is not exactly a one-liner. If you've ever developed programs to manage VMware in other languages, such as Perl or C#, this should look very familiar. Again, we have to refer to the VI SDK documentation to figure out what commands and parameters to use. The downside is the extra verbosity and complexity, but the upside is that anything that is possible in Virtual Center is possible in PowerShell, using the PowerShell toolkit you already have.

Do you have comments, questions or feedback? We're very interested in hearing your feedback about our layered approach. Do you agree with this approach? Do you feel you might adopt this approach in your scripts? Let us know what you think.


Regards,


Carter, for the VI Toolkit (for Windows) team.

Click to view halr9000's profile Master 814 posts since
Jun 7, 2007
I choose Option 1. :) Seriously though--that's an excellent approach. I hope others continue the trend. It's the 80/20 rule, right? Satisfy 80% but give the other 20% the means to extend things beyond that..
Click to view rfoust's profile Novice 6 posts since
Dec 21, 2007
I like this approach too. As long as something is possible (and documentation is available), I'm happy. I'd suggest publishing lots of examples like that in a "advanced vmware powershell scripting guide" to provide some general direction and to help newbies get started who need to do some customized scripting but who may not have much programming experience.

  • Robbie
Click to view bshell's profile Enthusiast 22 posts since
Apr 7, 2005
Awesome!
Click to view halr9000's profile Master 814 posts since
Jun 7, 2007
I just realized these cmdlets aren't in the release. Can we get them in the next build? I'd like to mess with it to see if I can figure out how to call CloneVM.
Click to view halr9000's profile Master 814 posts since
Jun 7, 2007
62# Get-PSSnapin vmware*

Name : VMware.VimAutomation.Core
PSVersion : 2.0
Description : This Windows PowerShell snap-in contains Windows Po...

63# Get-Command -PSSnapin (Get-PSSnapin vmware*) | Measure-Object
Count : 77

79# ls *.dll | Get-FileVersionInfo # gotta love PSCX

ProductVersion FileVersion FileName



1.0.0.0 1.0.0.0 C:\Program Files\VMware\PowerShell\VMware.VimAutomation.Client20.dll
1.0.0.0 1.0.0.0 C:\Program Files\VMware\PowerShell\VMware.VimAutomation.Common.dll
1.0.0.0 1.0.0.0 C:\Program Files\VMware\PowerShell\VMware.VimAutomation.dll
1.0.0.0 1.0.0.0 C:\Program Files\VMware\PowerShell\VMware.VimAutomation.Types.dll

I'm afraid that version #s mean nothing and that I'm really running the earlier version. I suspected this back when I was having the problem with VC 2.5, but as you may recall a reinstall seemed to fix that. It would be great if you were to put build #'s and minor version numbers in the beta builds...
Click to view halr9000's profile Master 814 posts since
Jun 7, 2007
/me is embarrassed!

Ok, I have 80-something cmdlets now! You guys added another snapin without me noticing. Right now I add these manually to my profile to be loaded, rather than using psc files.
Click to view LucD's profile Champion 2,437 posts since
Oct 31, 2005
Is there a way to get to the ServiceContent object using this method ?
Click to view halr9000's profile Master 814 posts since
Jun 7, 2007
What are you trying to do, LucD? I looked for a little bit but ran out of time. It's done totally different in Perl apparently (see http://www.vmware.com/support/developer/viperltoolkit/viperl15/doc/viperl_proggd.pdf p.23). The below is no help at all. :)

my $content = Vim::get_service_content();
Click to view LucD's profile Champion 2,437 posts since
Oct 31, 2005
I'm trying to get to the CustomizationSpecManager object.
From there I should be able to select the CustomizationSpec that I ultimately need for the CloneVM_Task method in the VirtualMachine object.

From the VI API Reference Guide (http://www.vmware.com/support/developer/vc-sdk/visdk25pubs/ReferenceGuide/index.html) I only found a pointer to the CustomizationSpecManager in the ServiceInstance.

With Carter's method I couldn't find a way to get to the ServiceInstance object.
Click to view halr9000's profile Master 814 posts since
Jun 7, 2007
Actually you don't need to do that, although I've never called this method. Here's how to get it:
77# Connect-Vim https://mojito/sdk
78# $vm = Find-EntityView -ViewType virtualmachine
89# $vm | gm clonevm_task | fl


TypeName   : VMware.Vim2.VirtualMachine
Name       : CloneVM_Task
MemberType : Method
Definition : VMware.Vim2.VimProxy.ManagedObjectReference CloneVM_Task(ManagedObjectReference f
             older, String name, VirtualMachineCloneSpec spec)


Note that this just gets the first VM on the stack. To get a particular one you have to make a filter like Carter explained.
Click to view adias's profile Enthusiast 43 posts since
Jan 9, 2008
Try something like this:


$svcRef = new-object VMware.Vim.ManagedObjectReference
$svcRef.Type = "ServiceInstance"
$svcRef.Value = "ServiceInstance"
$serviceInstance = get-view $svcRef
$csMgr = get-view $serviceInstance.Content.CustomizationSpecManager
$csMgr | gm

Click to view halr9000's profile Master 814 posts since
Jun 7, 2007
Something is wrong here...
92# $svcRef = new-object VMware.Vim.ManagedObjectReference
93# $svcref | gm

VMware Developer

SDKs, APIs, Videos, Learn and much more in the Developer community.

Learn More

Developer Sample Code

Increase your developer productivity with VMware API sample code.

Learn More

VMworld Sessions & Labs

Online access to the latest VMworld Sessions & Labs and online services.

Learn more

Purchase PSO Credits Online

Purchase credits to redeem training and consulting services online.

Buy Now

Community Hardware Software

View reported configurations or report your own.

Learn More

VMware vSphere

Come witness the next giant leap in virtualization.

Register Today

Communities