Using raw API objects with ExtensionData or Get-View
PowerCLI makes it easy to use the VMware vSphere application programming interface (API). There are two ways to do this. The first one is by using the ExtensionData
property that most of the PowerCLI objects have. The Extensiondata
property is a direct link to the vSphere API object related to the PowerCLI object. The second way is by using the Get-View
cmdlet to retrieve the vSphere API object related to a PowerCLI object. Both these ways will be discussed in the following sections.
Using the ExtensionData property
Most PowerCLI objects, such as VirtualMachineImpl
and VMHostImpl
, have a property called ExtensionData
. This property is a reference to a view of a VMware vSphere object as described in the "VMware vSphere API Reference Documentation". For example, the ExtensionData
property of the PowerCLI's VirtualMachineImpl
object links to a vSphere VirtualMachine
object view. ExtensionData
is a very powerful property because it allows you to use all of the properties and methods of the VMware vSphere API. For example, to see if the VMware Tools are running in your virtual machines, you can run the following command:
PowerCLI C:\> Get-VM | >> Select-Object -Property Name, >> @{Name = "ToolsRunningStatus" >> Expression = {$_.ExtensionData.Guest.ToolsRunningStatus} >> } >>
If VMware Tools are not installed in a virtual machine, the ExtensionData.Guest.ToolsStatus
property will have the value toolsNotInstalled
. You can check the tools' status with:
PowerCLI C:\> Get-VM | >> Select-Object -Property Name, >> @{Name = "ToolsStatus" >> Expression = {$_.ExtensionData.Guest.ToolsStatus} >> } >> Name ToolsStatus ---- ----------- VM1 toolsNotInstalled DNS1 toolsOk DC1 toolsNotRunning WindowsServer2012 toolsOld
Using the Get-View cmdlet
Another way to get the vSphere API objects is by using the Get-View
cmdlet. This cmdlet returns a vSphere object view, which is the same object you can retrieve via the ExtensionData
property. For example, the following two PowerCLI commands will give you the same result:
PowerCLI C:\> (Get-VM –Name vCenter).ExtensionData PowerCLI C:\> Get-VIew -VIObject (Get-VM -Name vCenter)
The Get-View
cmdlet has the following syntax:
Get-View [-VIObject] <VIObject[]> [-Property <String[]>] [<CommonParameters>] Get-View [-Server <VIServer[]>] [-SearchRoot <ManagedObjectReference>] -ViewType <Type> [-Filter <Hashtable>] [-Property <String[]>] [<CommonParameters>] Get-View [-Server <VIServer[]>] [-Id] <ManagedObjectReference[]> [-Property <String[]>] [<CommonParameters>] Get-View [-Property <String[]>] -RelatedObject <ViewBaseMirroredObject[]> [<CommonParameters>]
The names of the parameter sets are: GetViewByVIObject
, GetEntity
, GetView
, and GetViewByRelatedObject
. The second parameter set, GetEntity
, is very powerful and will allow you to create PowerCLI commands or scripts that are optimized for speed. For example, the following command will give you the vSphere object views of all virtual machines and templates:
PowerCLI C:\> Get-View –ViewType VirtualMachine
Possible argument values for the –ViewType
parameter are: ClusterComputeResource
, ComputeResource
, Datacenter
, Datastore
, DistributedVirtualPortgroup
, DistributedVirtualSwitch
, Folder
, HostSystem
, Network
, OpaqueNetwork
, ResourcePool
, StoragePod
, VirtualApp
, VirtualMachine
, and VmwareDistributedVirtualSwitch
.
If you want only the virtual machines and not the templates, you need to specify a filter:
PowerCLI C:\> Get-View –ViewType VirtualMachine –Filter @{" Config.Template" = "false"}
The filter is in the form of a hash table in which you specify that the value of the Config.Template
property needs to be false to get only the virtual machines.
To make your command run faster, you need to specify the properties that you want to return. Otherwise all of the properties are returned and that will make your command run slower.
Let's retrieve only the name and the overall status of your virtual machines:
PowerCLI C:\> Get-View -ViewType VirtualMachine -Filter @{"Config.Template" = "false"} -Property Name,OverallStatus | >> Select-Object -Property Name,OverAllStatus >>
This command runs in my test environment about 23 times faster than the equivalent:
PowerCLI C:\> Get-VM | Select-Object -Property Name, @{Name="OverallStatus";Expression={$_.ExtensionData.OverallStatus}}
The conclusion is: if you need your script to run faster, try to find a solution using the Get-View
cmdlet.
Tip
You should always make a trade-off between the time it takes you to write a script and the time it takes you to run the script. If you spend 10 minutes to create a script that takes one hour to run, you will have your work done in 70 minutes. If you spend two hours to create a faster script that runs in 10 minutes, you will have your work done in 130 minutes. I would prefer the first solution. Of course, if you intend to run the script more than once, the time you spend to improve the speed of your script is spent better.
Using Managed Object References
If you look at a vSphere object view using the Get-Member
cmdlet, you will see that a lot of properties are from type VMware.Vim.ManagedObjectReference
:
PowerCLI C:\> Get-VM -Name vCenter | Get-View | Get-Member | >> Where-Object {$_.Name -eq 'Parent'} >> TypeName: VMware.Vim.VirtualMachine Name MemberType Definition ---- ---------- ---------- Parent Property VMware.Vim.ManagedObjectReference Parent {get;}
A Managed Object Reference (MoRef) is a unique value that is generated by the vCenter Server and is guaranteed to be unique for a given entity in a single vCenter instance.
Using the Get-VIObjectByVIView cmdlet
The Get-View
cmdlet gives you a way to go from a PowerCLI object to a vSphere object view. If you want to go back from a vSphere object view to a PowerCLI object, you can use the Get-VIObjectByVIView
cmdlet. For example:
PowerCLI C:\> $VMView = Get-VM –Name vCenter | Get-View PowerCLI C:\> $VM = $VMView | Get-VIObjectByVIView
In the previous example, the first line will give you a vSphere object view from a PowerCLI VirtualMachineImpl
object. The second line will convert the vSphere object view back to a PowerCLI VirtualMachineImpl
object.
The Get-VIObjectByVIView
cmdlet has the following syntax:
Get-VIObjectByVIView [-VIView] <ViewBase[]> [<CommonParameters>] Get-VIObjectByVIView [-Server <VIServer[]>] [-MORef] <ManagedObjectReference[]> [<CommonParameters>]
You can see that the Get-VIObjectByVIView
cmdlet has two parameter sets. The first parameter set contains the –VIView
parameter. The second parameter set contains the –Server
and –MORef
parameters. Remember that parameters from different parameter sets cannot be mixed in one command.
If you are connected to multiple vCenter Servers, the Get-VIObjectByVIView
cmdlet might return objects from multiple vCenter Servers because MoRefs are only unique on a single vCenter Server instance. You can use the –Server
parameter of the Get-VIObjectByVIView
cmdlet to solve this problem by specifying the vCenter Server for which you want to return objects. Because the –Server
parameter is in a different parameter set from the –VIView
parameter, you cannot use the –VIView
parameter that is used in the pipeline. You have to use the ForEach-Object
cmdlet and the–MORef
parameter of the Get-VIObjectByVIView
cmdlet:
PowerCLI C:\> $VMView | >> ForEach-Object { >> Get-VIObjectByVIView -Server vCenter1 -MoRef $_.MoRef >> } >>
Note
In the name of the Get-VIObjectByVIView
cmdlet, you can see a piece of the history of PowerCLI. VMware vSphere was named VMware Infrastructure before VMware vSphere 4. The earlier VMware vSphere PowerCLI versions were called VI Toolkit. In the name of this cmdlet, you see that a PowerCLI object is still called a VIObject and a vSphere object view is called a VIView.