Learning PowerCLI
上QQ阅读APP看书,第一时间看更新

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.

Tip

The vSphere object views returned by the ExtensionData property or by the Get-View cmdlet are not the actual vSphere objects. The objects returned are copies or views of the actual objects that represent the actual objects at the time the view was made.

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.