Home > Blogs > VMware PowerCLI Blog > Tag Archives: PowerCLI 6

Tag Archives: PowerCLI 6

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”, “”)



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



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

Help us to help you with PowerCLI 6.0 R3

I present at a lot of User Groups, Events, Online presentations and of course VMworld and if you have ever sat in one of my sessions you will notice I always ask for feedback, I love hearing the good and the bad because ultimately it gets fed back into the products I help create at VMware and makes our customers lives easier.  I have to say as well that you are all great at giving me feedback, I enjoy walking away from VMworld and other sessions with a list of items we could improve on or are doing right and taking this back and adding it into our system to learn from and plan against in future releases.  Hopefully you see that this data as well as data from the communities, blog posts, conversations and numerous other places we look at gets fed straight back into the product.

Sometimes however there is data we need to make decisions that will help you and us in the future but is hard to get, other than spamming you all with online surveys and lets be honest, who doesn’t get enough of them to fill out?!

How can you help answer these questions?

Easy! You may have noticed that we recently released PowerCLI 6.0 Release 3 which can be downloaded from here and supports vSphere all the way back to vSphere 5.0 as well as a number of other products like vRealize Operations, VSAN, vCloud Air, vCloud Director etc etc (why wait, update now!).

One thing that was also introduced in this version was a way for me as the Product Manager to receive basic information to help me answer questions like, what versions of the OS are people using? What versions of PowerShell are they using? and a few other basic details, this is called “Customer Experience Improvement Support” (CEIP), it basically gives you the opportunity to give me feedback without even realizing it and therefore allowing me to make the product even better than before (I know you cant believe it can be right?!).

How do I send you this data and help make PowerCLI even more awesome?

First, make sure you install PowerCLI 6.0 Release 3 form here.

Second, launch PowerCLI from the PowerCLI Icon provided on your desktop or from the start menu.   The first time you launch this Icon you will be prompted to participate in the CEIP, just hit enter as the default answer is “J” for Join and then you are done, easy right! You can now sit back and enjoy that warm fuzzy feeling inside knowing that you are making the world of PowerCLI a better place.  This is a per user choice so each user that launches the icon for the first time will get the option to send back the data.

But what about scheduled tasks that run as a user I never log into? Don’t worry, notice I said it was the PowerCLI Icon you had to click on to get this prompt, if you just launch PowerShell and add the modules and snapins in the script or if you launch the ISE or another script editor you will notice you don’t get prompted for this and it will remain unset until the PowerCLI icon is clicked on for the first time.  This makes sure your scheduled tasks or scripts will still work fine.

But wait, I didn’t know about this and I already installed PowerCLI and declined sending you my data

Its ok, you can still be a helpful PowerCLI contributor, you can easily check what your current setting is by using the following command:

Get-PowerCLIConfiguration -Scope User | Select *CEIP*

You can also change the setting easily by using the Set-PowerCLIConfiguration to join the CEIP as follows:

PowerCLI C:\> Set-PowerCLIConfiguration -scope User -ParticipateInCeip $true

Perform operation?
Performing operation ‘Update vSphere PowerCLI configuration.’?
VMware’s Customer Experience Improvement Program (“CEIP”) provides VMware with
information that enables VMware to improve its products and services and to fix
problems. By choosing to participate in CEIP, you agree that VMware may
collect technical information about your use of VMware products and services on
a regular basis. This information does not personally identify you. For more
details: press Ctrl+C to exit this prompt and type “help about_ceip” to see the
related help article. You can join or leave the program at any time by
executing: Set-PowerCLIConfiguration -Scope User -ParticipateInCEIP $true or
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help
(default is “Y”):y

Scope    ProxyPolicy     DefaultVIServerMode InvalidCertificateAction  DisplayD
—–    ———–     ——————- ————————  ——–
Session  UseSystemProxy  Multiple            Unset                     True
User     UseSystemProxy

PowerCLI C:\> Get-PowerCLIConfiguration -Scope User  | Select *

DefaultVIServerMode         :
ProxyPolicy                 : UseSystemProxy
ParticipateInCEIP           : True
CEIPDataTransferProxyPolicy :
DisplayDeprecationWarnings  :
InvalidCertificateAction    :
WebOperationTimeoutSeconds  :
VMConsoleWindowBrowser      :
Scope                       : User


PowerCLI C:\>

What re you waiting for?

Next steps, download PowerCLI 6.0 R3, remember it works with versions all the way back to vSphere 5.0! and join the CEIP, help shape the product and build a better future for PowerCLI.

What’s New in PowerCLI 6.0 Webcast

Join our webcast Tuesday, July 7th at 9AM PST to see what’s new in PowerCLI 6.0 R1 and why this matters to you!  Registration is free, just click on the following link to register: https://vmware.webex.com/vmware/onstage/g.php?d=925268304&t=a


A recording of this webcast is available here: Play recording (45 min 13 sec)


PowerCLI: Continually Making Improvements for Quality Customer Experiences

It’s not every day that a product team can come out and say that they listen to their customers and continue to release new features and functionality asked for by it’s users. One of the wonderful opportunities I’ve had while working with our PowerCLI team is to see how focused they are on not only providing new features and functionality within different VMware products (allowing users to automate and administrate a number of key VMware products in their virtual environments), but also how actively they are listening to the feedback that YOU, the customer, are giving us. Continue reading

PowerCLI 6.0 R1 Is Now Generally Available


I am pleased to announce that vSphere PowerCLI 6.0 Release 1 is now Generally Available to the public. With this comes many great new features and functionality.

One of the great things that I love about PowerCLI is that although we are product-feature driven, we are also very much customer driven. Each new release tends to have several features or enhancements that have been asked for by YOU, our customers. These new features come to us by way of interaction at events like VMworld, Partner Exchange, VMUG Conferences, Twitter, Email, and customer visits. What better way to show our customers that we listen then by adding in features they ask for? This release does not disappoint! Thank you to all who provide feedback and help us continue to improve this great tool.

In this release PowerCLI meets VSANvCloud AirModules, and More! If that isn’t enough to spark interest in reading further, I don’t know what will! Without further ado:

What’s New in This Release Continue reading