Home > Blogs > VMware PowerCLI Blog

Using the entire API for vRealize Operations via PowerCLI

Previously we showed you how to use the useful cmdlets available with the PowerCLI vRealize Operations Manager (vR Ops) module, but as we also explained there are only a few cmdlets at the moment and anyone who knows vR Ops will know that there is a lot more functionality than is provided by those cmdlets.

But don’t worry, it is possible to access the entire vR Ops REST API!  PowerCLI gives us the ability to expand the capability of the module to perform many more tasks that aren’t available via the included cmdlets.

In this blog post, which is a continuation of my previous blog posts on the PowerCLI vR Ops module, I will explain how to access the entire vR Ops public REST API via PowerCLI.  Before I begin, it will be helpful to cover some basic information about the vR Ops REST API.

The API is available via the base URI of https://{vrops-IP}/suite-api and if you browse to this link the documentation is available.  For the most part, the API is pretty well documented with examples for usage including payloads for XML and JSON.  Below is a screenshot of the XML request body example for the performAction method.

clip_image002 Continue reading

Working with Recommendations and Statistics in vR OPs with PowerCLI

In our previous post you learned how to get started with using PowerCLI against vR Ops and how to use the cmdlets to work with alerts, in this post we take you a step further an learn how to take the work from the previous post and use it with Recommendations and Statistics from vR Ops.

As part of an alert which we discussed previously, vR Ops provides recommendations that guide you to possible solutions. These recommendations are available as well via the Get-OMRecommendation cmdlet. Continuing with the example, now that I have taken ownership of an alert I can easily grab the recommendation.


Continue reading

Getting started with PowerCLI for vRealize Operations (vR OPs)

I recently took some time to explore the PowerCLI module for vRealize Operations Manager (vR Ops). This module was released with PowerCLI 6.0 R2 last year and I can say that after a test drive I am really impressed at the capabilities of this new module. A useful set of cmdlets are provided and the entire vR Ops public API is accessible through this module.

In this blog post, I will cover some of the basics of the module and give some examples of usage including programmatically resolving an alert condition on a virtual machine. In these examples I am using PowerCLI 6.3 Release 1 with vRealize Operations Manager 6.2. I will follow this up with a more in-depth blog post explaining how the vR Ops API can be leveraged via PowerCLI.

To begin, the available cmdlets for the module (which is named “VMware.VimAutomation.vROps”) are shown below.

Continue reading

New Book: PowerCLI Essentials by Chris Halverson

What angle does this book give on PowerCLI?

imageThe book covers where to get PowerCLI and its history, including version differences and their change logs. Developing single line scripts into longer ones, reusable code and how to document your scripting.

Bridging scripts that pull key components of VMware scripting and incorporating Windows based calls in the same script, an introduction to vRealize Orchestrator and PowerShell Workflows and lastly incorporating PowerShell into other VMware products.

Who should buy this book, beginners, experts or all?

As this is an essentials book, the intended audience is the beginners to intermediate skill set, although I hope some points will be useful to even the most seasoned PowerShell scripter. This being said the ideal reader will be the VMware Administrator or the Windows Administrator that works with VMware products on a daily basis.

Where do we find the book



PACKT Website

Continue reading

PowerCLI 6.3 R1: Get-ESXCLI Why the V2?

If you have installed the latest release of PowerCLI (6.3 R1) then you may have noticed a warning if you have run the Get-ESXCLI cmdlet that looks a little like this:


What does it mean?

Whilst talking to the community and listening to our customers we heard that there were a couple of issues with this cmdlet, some that lead to problems with scripts breaking when being used against environments that have more than one version of ESX or maybe upgraded versions of ESX using older scripts with this cmdlet.  Lets take a bi of a deeper dive into these issues so you can understand why we made the change and how the new –V2 version is so much better!

Lets discuss the 2 main problems….

1. Positional values and the $null variable

When using the Get-ESXCLI cmdlet we would only allow invocation based on positional parameters, this was somewhat painful as providing just 1 parameter for a esxcli which had 15 options would result in long, weird looking scripts with a lot of $null parameters to fill the blanks, it was hard to work out which parameters where needed and where they fit in between the $null entires.  Lets take a look at the “ESXCLI network diag ping” namespace for example, to call this namespace and ping a given address twice in ESXCLI you would need to call the namespace with a –count and a –host option as per the docs here.  We would have had to find out where to put these when calling the Get-ESXCLI cmdlet and where to add the $null for everything we didn’t want to use.

Once done we would end up with a script which may look like the following:

$esxcli = Get-ESXCLI -VMHost (Get-VMhost | Select -first 1)


Not the most intuitive way to do things but it worked right?! Well, yeah kind of but that leads us to problem 2…

2.  Mixed environments or upgraded environments

One of the rules for updating ESXCLI namespaces is that you are allowed to add options but not remove or modify existing ones, this stops breaking changes for anyone using ESXCLI in a script, the issue was that when people were using these through PowerCLI and potentially using it against multiple hosts of different versions we could have a different number of $null parameters as we need one for every parameter we don’t use.

For example, we may have the following example in ESX 5.1:

$esxcli = Get-ESXCLI -VMHost (Get-VMhost | Select -first 1)


This may work fine but then what if we at VMware extending this namespace to give it an extra option, we would need an extra $null through Get-ESXCLI, so for example in ESX 5.5 this may be:

$esxcli = Get-ESXCLI -VMHost (Get-VMhost | Select -first 1)


As you can see, if we ran either the 5.1 version against a 5.5 hosts or the 5.5 version against the 5.1 host we would have errors and broken scripts.  Of course you could check for each version but this starts to get complex when sharing scripts for others to use and the multiple versions of esxcli namespaces we have out there.

So what does V2 do that’s different?

The Get-ESXCLI cmdlet has now been updated with a –V2 parameter which supports specifying method arguments by name, essentially we are able to fix both issues above and provide an easier way to explore what an ESXCLI namespace requires and allow us to provide only the items we care about, lets walk though the same example but using the –V2 switch

Firstly lets store the new version in a variable like we did above:

$esxcli2 = Get-ESXCLI -VMHost (Get-VMhost | Select -first 1) -V2

Next we can find out what options are available to set for the namespace by calling the new CreateArgs method and storing this in a variable:

$arguments = $esxcli2.network.diag.ping.CreateArgs()

Now we can see what’s in the variable by calling it:

PowerCLI C:\> $arguments

Name                           Value
—-                           —–
host                           Unset, ([string], optional)
wait                           Unset, ([string], optional)
df                             Unset, ([boolean], optional)
interval                       Unset, ([string], optional)
ttl                            Unset, ([long], optional)
debug                          Unset, ([boolean], optional)
nexthop                        Unset, ([string], optional)
count                          Unset, ([long], optional)
netstack                       Unset, ([string], optional)
size                           Unset, ([long], optional)
ipv4                           Unset, ([boolean], optional)
ipv6                           Unset, ([boolean], optional)
interface                      Unset, ([string], optional)

As you can see, its helped us out here, it has prefilled this array with the options we can specify, now all we need to do is assign values to the entries we want to use:

$arguments.count = 2

$arguments.host = “”

If we look at what’s in the variable again we can see we have set just the two entries we need:

PowerCLI C:\> $arguments

Name                           Value
—-                           —–
wait                           Unset, ([string], optional)
df                             Unset, ([boolean], optional)
interval                       Unset, ([string], optional)
ttl                            Unset, ([long], optional)
debug                          Unset, ([boolean], optional)
nexthop                        Unset, ([string], optional)
count                          2
netstack                       Unset, ([string], optional)
size                           Unset, ([long], optional)
ipv4                           Unset, ([boolean], optional)
ipv6                           Unset, ([boolean], optional)
interface                      Unset, ([string], optional)

Next all we need to do is send these options back by using the Invoke method and providing our set $arguments variable:


lets put this together so you can see how easy this is now:

$esxcli2 = Get-ESXCLI -VMHost (Get-VMhost | Select -first 1) -V2

$arguments = $esxcli2.network.diag.ping.CreateArgs()

$arguments.count = 2

$arguments.host = “”



As you can see, not only is this much easier to understand but we also don’t have to use lots of $null entries and it will also work against multiple versions of ESXi or allow you to share your scripts knowing that they will work against any version of ESXi that supports the namespaces you used in ESXCLI.

A Win, Win situation here, so why wouldn’t you use the –V2 option?!

PowerCLI Best Practice: Correct Use of Strong Typing

All software is changed over time to allow for improvements, this ensures it is providing the best experience for the user and evolving into a better product. PowerCLI is no exception! Yet, as you know PowerCLI is not the typical GUI application where we can move a text box or change the color of a button. Once written, scripts require that every piece of PowerCLI they use retains that same functionality in future versions, this is something we take seriously at VMware as we don’t want to break existing scripts that have been written but clearly do want to move the product forward.

In order to do this we need to provide you, the users of PowerCLI with a compatibility contract. A contract which states which elements are guaranteed to stay the same, and which elements may change. Scripts are supposed to rely on the areas which stay the same and steer clear of the areas we may change to provide a better user experience.

As a general rule of thumb, PowerShell-style use of PowerCLI is safe. This includes cmdlets and their parameters and retrieving the values of properties in objects returned by cmdlets. What is not safe is the .Net programming-style use of PowerCLI, for example relying on the specific types of objects, whilst looking at scripts in the community and talking to customers we have seen a trend which may cause issues when followed.  We want the best for our customers and to keep you informed on what we consider a best practice when using types and therefore we would like to explain a little more about this, we want to ensure this is being used in the correct way and that your scripts are written to always be safe with the changes we make.

I’ll focus on one particular aspect of compatibility which was affected by changes in Get-VM in the recently released PowerCLI 6.3. Script authors often explicitly specify the types of parameters in a function. This adds an extra layer of reliability, especially in highly reusable functions:

function MyFunction([Full.Type.Name.Goes.Here] $myObject)

Or, sometimes types are used to check an input and take different action depending on the type of an object:

if ($myObject -is [Full.Type.Name.Goes.Here]) { … }

But how do you get the correct type name to use here? Use $myObject.GetType() or Get-Member, right? These methods indeed return the actual implementation type of the object. For a VM, the result is “VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl”.

Unfortunately, PowerCLI cannot guarantee that the implementation type won’t change in the future. There are scripts that we have seen that rely on implementation types (see that “impl” in the name?) and these scripts occasionally break when bigger changes need to be made in PowerCLI, this clearly can cause issues, issues we would prefer you didn’t get and therefore we would like to give you a best practice on what we think the safest way to do this actually is, so if you are using types in your scripts you can continue to do this and ensure any future changes we make will not impact you.

The approach we would suggest is to use what the PowerCLI team calls the “.Types” interface. “.Types” is a set of types which is guaranteed to maintain compatibility with scripts, across different PowerCLI versions. The “.Types” type for e.g. a VM is “VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine”.  Note how the “.Impl” part of the name is now replaced by “.Types”.

This brings us to the question, how do you get the correct “.Types” type for a given object?  

Basically, any type in the “Types” namespace, implemented by your object is ok to use. But usually the closest match is a type which has the same name as the implementation type but without the “Impl” suffix. So usually the following will get you the type name:

$myType = $myObject.GetType()

$compatibleTypeName = $myType.Name.Replace(“Impl”, “”)


$myType.GetInterfaces() `

    | where { $_.FullName -like “*.Types.*” -and $_.Name -eq $compatibleTypeName } `

    | select FullName


If it doesn’t find the type you are looking for, you can still examine the full list of supported “.Types” types and pick the one you like best:


$myObject.GetType().GetInterfaces() `

    | where { $_.FullName -like “*.Types.*” } `

    | select FullName

Here’s what the previous examples look like once the implementation types are replaced by the correct compatible types:


function MyFunction([VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl] $myObject)

if ($myObject -is [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl]) { … }




function MyFunction([VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $myObject)

if ($myObject -is [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine]) { … }

All of the above can come in handy to you particularly if you have scripts which use the “VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl” type. In PowerCLI 6.3, Get-VM cmdlet performance was optimized and, as a result, the type of objects returned by the cmdlet needed to change to “VMware.VimAutomation.ViCore.Impl.V1.VM.UniversalVirtualMachineImpl”. The change affects cases where the call to Get-VM does not specify filtering by the parent object, such as VMHost. With PowerCLI 6.3, calls such as plain Get-VM or Get-VM –Name ‘infra*’ return objects of the new UniversalVirtualMachineImpl type.

To detect problematic scripts which may be affected by future PowerCLI changes, you can search for the “VMware.VimAutomation.*.Impl.*” string. 

To detect scripts which are likely to be affected specifically by the recent Get-VM change, search for the “VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl” string and use “VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine” instead.

Free PowerCLI Training (or a test lab) now available

You still haven’t learned PowerCLI?  What are you waiting for?

Now, you have no excuse, recently we split out the PowerCLI content into its own lab to allow you to get started with PowerCLI for FREE!

The PowerCLI lab contains a step by step course on PowerCLI enabling you to go from a beginner all the way to an expert, its a handy way to learn in the safe knowledge that you will not harm anything in your environment.

It also makes for a great test lab for testing your scripts, did you know you can paste your code into the environment, here is how:


Learn more from the PM in this quick video

Where do I go to get started?

You can take the lab by visiting http://vmware.com/go/PowerCLILab

New release: PowerCLI 6.3 R1–Download it today!

It is my pleasure to inform you that vSphere PowerCLI 6.3 Release 1 has now been released and as usual we have some great features to ensure you are able to automate even more features and in this release, faster than ever!  As always we take feature requests directly from customers, through feedback at conferences, by looking at the communities and multiple other ways. please do keep giving us your feedback to enable us to keep making the product easier and making automation tasks less painful.

PowerCLI 6.3 R1 introduces the following new features and improvements:


Get-VM is now faster than ever!

imageThe Get-VM Cmdlet has been optimized and refactored to ensure maximum speed when returning larger numbers of virtual machine information. This was a request which we heard time and time again, when you start working in larger environments with thousands of VMs the most used cmdlet is Get-VM so making this faster means this will increase the speed of reporting and automation for all scripts using Get-VM. Stay tuned for a future post where we will be showing some figures from our test environment but believe me, its fast!


New-ContentLibrary access

imageNew in this release we have introduced a new cmdlet for working with Content Library items, the Get-ContentLibraryItem cmdlet will list all content library items from all content libraries available to the connection. This will give you details and set you up for deploying in our next new feature….

The New-VM Cmdlet has been updated to allow for the deployment of items located in a Content Library. Use the new –ContentLibrary parameter with a content library item to deploy these from local and subscribed library items, a quick sample of this can be seen below:

$CLItem = Get-ContentLibraryItem TTYLinux
New-VM -Name “NewCLItem” -ContentLibraryItem $CLItem -Datastore datastore1 -VMHost

Or even simpler….

Get-ContentLibraryItem -Name TTYLinux | New-VM -Datastore datastore1 -VMHost


ESXCLI is now easier to use

Another great feature which has been added has again come from our community and users who have told us what is hard about our current version, the Get-Esxcli cmdlet has now been updated with a –V2 parameter which supports specifying method arguments by name.

The original Get-ESXCLI cmdlet (without -v2) passes arguments by position and can cause scripts to not work when working with multiple ESXi versions or using scripts written against specific ESXi versions.

A simple example of using the previous version is as follows:

$esxcli = Get-ESXCLI -VMHost (Get-VMhost | Select -first 1)


Notice all the $nulls ?  Now check out the V2 version:

$esxcli2 = Get-ESXCLI -VMHost (Get-VMhost | Select -first 1) -V2

$arguments = $esxcli2.network.diag.ping.CreateArgs()

$arguments.count = 2

$arguments.host = “”



Get-View, better than ever

imageFor the more advanced users out there, those who constantly use the Get-View Cmdlet you will be pleased to know that a small but handy change has been made to the cmldet to enable it to auto-complete all available view objects in the Get-View –ViewType parameter, this will ease in the use of this cmdlet and enable even faster creation of scripts using this cmdlet.


Updated Support

As well as the great enhancements to the product listed above we have also updated the product to make sure it has now been fully tested and works with  Windows 10 and PowerShell v5, this enables the latest versions and features of PowerShell to be used with PowerCLI.

PowerCLI has also been updated to now support vCloud Director 8.0 and vRealize Operations Manager 6.2 ensuring you can also work with the latest VMware products.


More Information and Download

For more information on changes made in vSphere PowerCLI 6.3 Release 1, including improvements, security enhancements, and deprecated features, see the vSphere PowerCLI Change Log. For more information on specific product features, see the VMware vSphere PowerCLI 6.3 Release 1 User’s Guide. For more information on specific cmdlets, see the VMware vSphere PowerCLI 6.3 Release 1 Cmdlet Reference.

You can find the PowerCLI 6.3 Release 1 download HERE. Get it today!

Managing the Virtual Machine Lifecycle with PowerCLI


Following the last videos showing an introduction to PowerCLI and Reporting in PowerCLI there is now a new video that takes you through managing the virtual machine lifecycle with PowerCLI, these videos are a fantastic, quick way to learn PowerCLI tips and tricks.

Administrators are no longer responsible for managing single digit servers, they now have hundreds or even thousands to maintain. The automation capabilities of PowerCLI allow you to manage the lifecycle of a single virtual machine, or a large number of virtual machines, by using custom scripts.

Every stage of the virtual machine lifecycle, from creation and modification to migration and deletion, can be automated with just a few lines of PowerCLI code. What’s more, the number of virtual machines that you are managing, has no significant impact on the complexity of the PowerCLI scripts that you need to use.

This latest video shows how to perform the following tasks easily:

  • Create a single VM
  • Deploy a VM from a Template
  • Deploy a VM using a customization specification
  • Deploying VMs from a CSV file into multiple folders
  • Change resources assigned to a VM (CPU/Mem)
  • Move a large number of VMs from one network to another
  • Move VMs to a new folder
  • vMotion VMs between hosts
  • Storage vMotion VMs to a new datastore
  • Remove Virtual Machines

All this in under 5 minutes!

Watch the video


Updated Book: PowerCLI Book 2nd Edition

9781118925119.pdfThere is a new book on the market for PowerCLI, well I say new but really I mean updated but that does not by any means make it less valuable! The first edition of this book was a great success and I personally often ran into many people who would use this as the go to place to learn about real world examples of how to achieve common tasks with PowerCLI and how to take their PowerCLI knowledge even further.

Now there is a second edition of the book with a star studded list of authors, some of which have changed since the first edition.  With names like Luc Dekens, Jonathan Medd, Glenn Sizemore, Brian Graf, Andrew Sullivan and Matt Boren this book should take pride of place on any good VMware Admins desk who wants to achieve automation and make their lives easier.

So what’s changed?

Well, firstly the VMware products! The first version was written in in 2010 and published in 2011, since then PowerCLI and also the VMware products have been enhanced dramatically to include new versions and new features which all need automation.  Secondly the skills of the people writing it, I know personally that when I go back and look at scripts I may have written a couple of years ago I cringe and wish I had time to go back and use the latest version of PowerShell and my updated PowerShell super powers to ensure the scripts are bang up to date an as efficient as they need to be.  This book has certainly done that, its been updated so that you can automate the latest and greatest features and use the latest and greatest PowerShell versions with all then enhancements it provides.  For example, the addition of the following product areas in the book make the 2nd edition a must for even those who own the first edition:

  • vCloud Director
  • vCloud Air
  • vRealize Orchestrator
  • Site Recovery Manager
  • PowerActions
  • and an introduction to DevOps topics

Where can I buy this awesome book?

The following links can be used to purchase the book:

Amazon USA

Amazon UK



More Information

Jonathan has written a great blog post on not only the book but also an insiders perspective on what it took to update the book.  Personally as I was unable to give the time needed to update this book I can only congratulate the authors for an awesome job and the time they dedicated. Read Jonathans post here: http://www.jonathanmedd.net/2016/01/powercli-book-2nd-edition-is-now-available.html

The sample scripts that are written in the book can be found on the Wiley page here: http://www.wiley.com/WileyCDA/WileyTitle/productCd-1118925114.html