Home > Blogs > VMware PowerCLI Blog

Which Version of PowerCLI is Right For Me?

“I have PowerCLI 5.5 installed because I manage a vSphere 5.5 environment. I’ll update to PowerCLI 6.0 when I upgrade my vSphere environment to 6.0.”

Sound familiar? This is one of the most common things we hear during VMUGs, customer meetings, and around the community in general. This also happens to be a HUGE misconception. The current version is PowerCLI 6.3 Release 1 and it is compatible with all the supported vSphere versions!

Don’t take my word for it, check out the compatibility matrix:
PowerCLI Compatibility

As displayed in the compatibility matrix above, significant effort has been made to ensure backward compatibility while still being able to offer all of the latest and greatest updates and feature enhancements.

At this point you’re probably wondering what version of PowerCLI you’re using? Open up your PowerCLI window and have a look at the “Get-PowerCLIVersion” cmdlet:


PowerCLI is extremely backward compatible and we highly recommend upgrading to the latest version: PowerCLI 6.3 Release 1.

Take advantage of the following benefits:

  • Get-VM cmdlet optimizations
    Saying Get-VM is faster is just an understatement, some of the numbers we’ve received from the community are amazing!
  • Get-View cmdlet improvements
    Get-View now allows for tab completion of the -ViewType parameter
  • Added Content Library functionality
    The new Get-ContentLibraryItem cmdlet retrieves Content Library items as well as the ability to specify a Content Library item while using the New-VM cmdlet.
  • Get-ESXCLI improvements
    Major upgrade to the Get-ESXCLI cmdlet to now allow the passing of arguments by name instead of position simply by adding the -V2 parameter
  • Added PowerShell v5 and Windows 10 support
  • Added support for the following VMware products: vCloud Director 8.0 and vRealize Operations Manager 6.2

A couple notable resolved issues:

  • Get-VM
    If you try to run Get-VM without specifying any parameters, you might receive an error message of type Value cannot be null.
  • Export-EsxImageProfile
    If you try to export an image profile, you receive an error message of type Cannot instantiate ‘certified’ policy: VibSign module missing.
  • New-DeployRule
    If you try to create a new deploy rule by passing absolute values of host profle, cluster, datacenter, or folder instead of passing the objects, you receive an error message of type Cannot process argument transformation on parameter ‘Item’. Unsupported version URI urn:rbd1/3.0.

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.

Upgrade by heading over to the vSphere PowerCLI page and downloading it today!

Welcome a new face to the team


3TSeV8RqYou are about to see new and exciting blog posts arrive from a fresh face on the team.  Please do join me in welcoming the new Technical Marketing expert on all things PowerCLI – Kyle Ruddy.

Kyle works as part of our Technical Marketing team, being responsible for vSphere Operations Management and will also cover APIs / SDKs and CLIs.

Kyle has been a big fan of PowerCLI, and automation in general, having technically reviewed PowerCLI books, presented PowerCLI based VMUG sessions, and been a strong community contributor. Kyle’s focus will be to continue evangelizing PowerCLI and its use to help VMware customers increase their productivity and consistency and to bring you the latest and greatest in news and new ways to use PowerCLI.

During his spare time, Kyle enjoys golfing, SCUBA diving, and most motorsports activities.


You can find Kyle’s personal blog at http://thatcouldbeaproblem.com and can contact him on twitter via @kmruddy

Blogger Talk Show–Pilot Episode on PowerCLI

Here at VMware we are always trying to make sure we give you the information you need in a way that you can best consume it.

With this in mind, a little while ago I was asked to take part in a pilot for a new talk show VMware is looking to gain feedback on, this gives us the chance to give you more information in a less formal way and you to learn more about a given subject.

The initial talk show is a little rough around the edges but please do take 30 minutes out of your busy schedule to check it out and perhaps learn a little more about PowerCLI and how to work with VMs in particular.

Watch the video

Continue reading

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