vSphere 6.7 was released a couple weeks ago and there were a ton of new features announced. However, there was one feature I was particularly interested in and that was Per-VM EVC (Enhanced vMotion Compatibility).

Giving a brief, high-level overview, EVC can be used to set a baseline of CPU features available to a VM or a set of VMs. In the past, this was a cluster-based setting. It was really nice because you could take hosts which didn’t have the same CPUs, use EVC to apply a common CPU baseline, and still put them in a cluster to take advantage of features like DRS and HA. The problem is that once a VM left that cluster, the EVC configuration would no longer be enforced. With vSphere 6.7 that changes, EVC can now be applied at the VM object level. This is awesome because now a VM can move across clusters, across datacenters, or even out to VMware Cloud on AWS and remain powered on and compatible! Be on the lookout for a much deeper dive on Per-VM EVC by my counterpart Emad Younis shortly.

Currently, configuring a VM’s EVC mode with PowerCLI is only available through a low-level command. That means, to configure this setting, we’re going to need to use methods that are exposed through either Get-View or a VM’s ExtensionData.

Let’s take a look at how we can automate this new setting using PowerCLI!

Introduction

First things first, we need to cover some requirements. To configure Per-VM EVC we need a couple things, including:

  • vSphere 6.7 (vCenter and ESXi host version)
  • A VM with hardware version 14
  • PowerCLI 10.1.0

Once we have those all inline, we need to figure out what EVC mode is appropriate for this particular VM.

Determining the Desired EVC Mode

PowerCLI makes it extremely easy to figure out what EVC modes are available. Each ESXi host object has a top-level property we can use to discover what their maximum EVC mode is. Once we obtain that information from all the potential hosts, we choose the lowest baseline and configure the VM with that.

Obtaining an ESXi host’s maximum EVC mode can done with the following command:

Get-VMHost | Select-Object Name,MaxEVCMode

Example: Discovering VMHost MaxEVCMode

From the above example, we can see that the VM’s EVC mode should be no higher than ‘intel-sandybridge’ to work on these hosts. If we anticipate moving this VM between vCenters, we would want to run the same command against the ESXi hosts managed by that vCenter. If we anticipate moving this out to VMware Cloud on AWS, we already know those hosts are configured to be at an EVC mode of ‘intel-broadwell’. Broadwell is a higher, more advanced, mode than Sandy Bridge, so we’re still going to use the Sandy Bridge mode for our VM.

For more details about each EVC mode and how they rank, see the following KB article: 1003212 - Enhanced vMotion Compatibility (EVC) processor support

Assigning EVC Mode

We’re now ready to configure the per-VM EVC mode for this particular VM. The method we’ll be using is ‘ApplyEvcModeVM_Task’. More information about this can be found in the vSphere 6.7 Web Services API: ApplyEvCModeVM_Task

Based on the documentation, we have a couple parameters available to use:

ParameterType
maskcompleteMask
HostFeatureMask ObjectBoolean

The ‘mask’ parameter is looking for the CPU masking features we wish to configure. This is where the API gets a little more advanced than the UI. Where the UI only allows us to set the top level EVC mode, the API enables us to either specify all the feature masks which correlate to the EVC mode or be as granular as to only specify specific masks, the choice is ours. To be clear, this method does not accept the top-level EVC mode as input. Personally, I configure all the feature masks so that the VM’s level is aligned with the top level EVC mode.

The second parameter is ‘completeMasks’. This parameter is essentially asking if the masks presented are the complete list of masks to enable for this VM. This parameter accepts true or false as input and defaults to true. This is another reason I, personally, specify all the feature masks because then there is no confusion over what is or is not enabled for the virtual machine object.

Before we run the method, we need to obtain a list of feature masks. Starting from a high level, we can obtain the EVC Modes which are supported by our present vCenter with the following command:

$global:DefaultVIServer.ExtensionData.Capability.SupportedEVCMode

To only retrieve information about the ‘intel-sandybridge’ mask, we can add a ‘where’ statement searching for that as the ‘key’ property:

$evcMode = $global:DefaultVIServer.ExtensionData.Capability.SupportedEVCMode
$evcMode | Where-Object {$_.key -eq 'intel-sandybridge'}

Then, to isolate the masks we will be using as inputs for the ‘mask’ parameter, we can store the ‘FeatureMask’ output into a variable:

$evcSB = $evcMode | Where-Object {$_.key -eq 'intel-sandybridge'}
$featureMasks = $evcSB | Select-Object -ExpandProperty FeatureMask

The above can also be wrapped up into a one-liner with the following command:

$featureMasks = $global:DefaultVIServer.ExtensionData.Capability.SupportedEVCMode | Where-Object {$_.key -eq 'intel-sandybridge'} | Select-Object -ExpandProperty FeatureMask

We’re now ready to run the command as follows:

$vm.ExtensionData.ApplyEvcModeVM_Task($featureMasks,$true)

Putting It All Together

If we combine all of the code above, it will look like the following:

Get-VM -Name file02 | select Name,HardwareVersion,@{Name='EvcMode';Expression={$_.ExtensionData.Runtime.MinRequiredEVCModeKey}}
$vm = Get-VM -Name file02
Get-VMHost | Select-Object Name,MaxEVCMode
$featureMasks = $global:DefaultVIServer.ExtensionData.Capability.SupportedEVCMode | Where-Object {$_.key -eq 'intel-sandybridge'} | Select-Object -ExpandProperty FeatureMask
$vm.ExtensionData.ApplyEvcModeVM_Task($featureMasks,$true)
Get-VM -Name file02 | select Name,HardwareVersion,@{Name='EvcMode';Expression={$_.ExtensionData.Runtime.MinRequiredEVCModeKey}}

Example: Putting everything together to set Per-VM EVC mode of a single VM

In 6 lines of code, we’ve gone from a VM with no EVC mode to a VM configured with an EVC mode of ‘intel-sandybridge’!

Community Module

If you found all the above to be a little too cumbersome, there’s a community module you can use to simplify this entire process. This module is available on the PowerCLI Community Repository: PerVMEVC

The PerVMEVC module provides the following three functions:

  • Get-VMEvcMode
  • Remove-VMEvcMode
  • Set-VMEvcMode

Here’s an example of them in action: Example: Community Module Usage

Summary

vSphere 6.7 came packed with new features. One feature in particular really enables VMs the mobility to run anywhere. That feature is Per-VM EVC. This new feature takes the cluster based EVC functionality we’re already familiar with and now makes it available at the VM object level. PowerCLI gives us the ability to automate the entire process through the API using the ‘ApplyEvcModeVM_Task’ method as well as a new community module that can be used to simplify the process!