admin
Immortal
Immortal

How To: Accessing the entire Virtual Infrastructure API from PowerShell.

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.

  1. Power on a virtual machine: cmdlet version.

  1. Connect to the ESX/VC server.

get-viserver -server <IP Address> -user <User> -password <Pass>

  1. Power on the VM.

get-vm <VMName> | start-vm

Compare this with the managed object approach:

  1. Power on a virtual machine: managed object version.

  1. First, connect to the ESX server.

get-viserver -server <IP Address> -user <User> -password <Pass>
#
  1. Build a filter to specify a specific virtual machine.

$nvc = new-object System.Collections.Specialized.NameValueCollection
$nvc.Add("name", "<VMName>")
#
  1. Find the virtual machine. $vm is the virtual machine managed object.

$vm = find-entityview -viewtype VirtualMachine -filter $nvc
#
  1. 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.

  1. Connect to the ESX server.

get-viserver -server <IP Address> -user <User> -password <Pass>
#
  1. Build a filter to specify a specific virtual machine.

$nvc = new-object System.Collections.Specialized.NameValueCollection
$nvc.Add("name", "<VM Name To Find>")
#
  1. Get the VM we want to reconfigure.

$vm = find-entityview -viewtype VirtualMachine -filter $nvc
#
  1. Get the HostSystem. If you're using Virtual Center, use a filter to

  1. select a particular host.

$hostSystem = find-entityview -viewtype HostSystem
$autoStartRef = $hostSystem.configManager.autoStartManager
$autoStartManager = get-view -MoRef $autoStartRef
#
  1. Configure the VM to start first, after 60 seconds. We do this by

  1. 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"
#
  1. Wrap the argument above in the variable used by reconfigureAutostart.

$config = new-object VMware.Vim.VimProxy.HostAutoStartManagerConfig
$config.PowerInfo = $powerInfo
#
  1. 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.

0 Kudos
21 Replies
halr9000
Commander
Commander

I choose Option 1. Smiley Happy 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..

My signature used to be pretty, but then the forum software broked it. vExpert. Microsoft MVP (Windows PowerShell). Author, Podcaster, Speaker. I'm @halr9000
0 Kudos
rfoust
Contributor
Contributor

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

0 Kudos
bshell
Enthusiast
Enthusiast

Awesome!

0 Kudos
halr9000
Commander
Commander

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.

My signature used to be pretty, but then the forum software broked it. vExpert. Microsoft MVP (Windows PowerShell). Author, Podcaster, Speaker. I'm @halr9000
0 Kudos
admin
Immortal
Immortal

These cmdlets are in the December release, are you sure you're not using the earlier toolkit?

Carter

(P.S. It is possible to call CloneVM using them, if I get a few minutes later today I'll post an example.)

0 Kudos
halr9000
Commander
Commander

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...

My signature used to be pretty, but then the forum software broked it. vExpert. Microsoft MVP (Windows PowerShell). Author, Podcaster, Speaker. I'm @halr9000
0 Kudos
admin
Immortal
Immortal

The view and entity views cmdlets are, for the time being anyway, in the VIPowerShellCommandsSnapIn. In my environment,

-


PS C:\> get-command -pssnapin (get-pssnapin vipowershell*)

CommandType Name Definition

-


-


-


Cmdlet Connect-Vim Connect-Vim <String> ...

Cmdlet Disconnect-Vim Disconnect-Vim [-...

Cmdlet Find-EntityView Find-EntityView ...

Cmdlet Find-EntityViews Find-EntityViews ...

Cmdlet Get-View Get-View <ManagedOb...

Cmdlet Get-Views Get-Views ...

Cmdlet Load-Session Load-Session -FileName <Stri...

Cmdlet Save-Session Save-Session -FileName <Stri...

-


Do you have this snapin in your environment?

Also, we will definately add ways of easily determining which version you're running.

0 Kudos
halr9000
Commander
Commander

/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.

My signature used to be pretty, but then the forum software broked it. vExpert. Microsoft MVP (Windows PowerShell). Author, Podcaster, Speaker. I'm @halr9000
0 Kudos
LucD
Leadership
Leadership

Is there a way to get to the ServiceContent object using this method ?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
halr9000
Commander
Commander

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 p.23). The below is no help at all. Smiley Happy

my $content = Vim::get_service_content();

My signature used to be pretty, but then the forum software broked it. vExpert. Microsoft MVP (Windows PowerShell). Author, Podcaster, Speaker. I'm @halr9000
0 Kudos
LucD
Leadership
Leadership

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.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
halr9000
Commander
Commander

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.

My signature used to be pretty, but then the forum software broked it. vExpert. Microsoft MVP (Windows PowerShell). Author, Podcaster, Speaker. I'm @halr9000
0 Kudos
admin
Immortal
Immortal

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

0 Kudos
halr9000
Commander
Commander

Something is wrong here...

92# $svcRef = new-object VMware.Vim.ManagedObjectReference
93# $svcref | gm

My signature used to be pretty, but then the forum software broked it. vExpert. Microsoft MVP (Windows PowerShell). Author, Podcaster, Speaker. I'm @halr9000
0 Kudos
admin
Immortal
Immortal

I don't have the right build installed. I can check later but as a guess maybe try something like:


$svcRef = new-object VMware.Vim2.VimProxy.ManagedObjectReference

0 Kudos
LucD
Leadership
Leadership

Thanks, that last one did the trick.

connect-vim -url https://app1/sdk

$svcRef = new-object VMware.Vim2.VimProxy.ManagedObjectReference

$svcRef.Type = "ServiceInstance"

$svcRef.Value = "ServiceInstance"

$serviceInstance = get-view $svcRef

$csMgr = get-view $serviceInstance.Content.CustomizationSpecManager

$csItem = $csMgr.GetCustomizationSpec("SpecName")

With this construct I think I can now change specific parameters like for example ComputerName and IPAddress.

And then finally execute the CloneVM_task method.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
LucD
Leadership
Leadership

With the arrival of the beta (build 81531) the previous construct now becomes:

$cred = get-credential <my-account.

get-viserver -server -credentials $cred

$svcRef = new-object VMware.Vim.ManagedObjectReference

$svcRef.Type = "ServiceInstance"

$svcRef.Value = "ServiceInstance"

$serviceInstance = get-view $svcRef

$csMgr = get-view $serviceInstance.Content.CustomizationSpecManager

$csItem = $csMgr.GetCustomizationSpec("SpecName")


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
hugopeeters
Hot Shot
Hot Shot

I think the concept is great. I love being able to unlock the full power of the API for advanced scripting tasks.

But I think it is not being explained well enough. This thread is a great start though!

I am planning to write an easily accessible post on my blog sometime soon. In the meantime, I will publish some of my scripts, so everybody can learn from the examples.

Check out my first script: Set-MultipathPolicy: http://www.peetersonline.nl/index.php/vmware/vi-toolkit-advanced-script-set-multipathpolicy

0 Kudos
hugopeeters
Hot Shot
Hot Shot

There you go: I have tried to explain the use of Get-View(s) and Find-EntityView(s) to unlock the power of the API a bit more clearly in the following post:

I hope you'll find it useful.

Regards,

Hugo Peeters

0 Kudos