PowerCLI

 View Only

 PowerCLI - How to check Vmotion compatibilty

alpatio's profile image
alpatio posted May 14, 2025 10:53 AM

Hello,

I'll have to migrate lot of Virtual machines from one cluster with older ESX to a another cluster with new hardware, and both cluster source and destination has enabled EVC mode

I've wrote a Powercli script to perform the move, and I've added a pre-check code to verify that Virtual Machine is able to run on the new Cluster

I'm using a code like this:

            # Check VM-Host compatibility using the vSphere API - proper method
            $viewSI = Get-View 'ServiceInstance'
            $viewVmProvChecker = Get-View $viewSI.Content.VmProvisioningChecker
            $compatibilityResult = $viewVmProvChecker.QueryVMotionCompatibilityEx(@($vm.Id), @($dstHost.Id))

The code works, but in some Virtual Machine it reports some compatibility errors (others than network) related to some CPU functions..

Network will be changed during migration

Errors are:

Fault                                LocalizedMessage                                                                                                                                    
-----                                ----------------                                                                                                                                    
VMware.Vim.FeatureRequirementsNotMet The target host does not support the virtual machine's current hardware requirements.                                                               
VMware.Vim.CannotAccessNetwork       Currently connected network interface 'Network adapter 1' uses network 'DVSwitch: 50 33 8d 03 c8 50 1d a3-b9 b9 40 2a 3a 11 6c 2a', which is not ...
VMware.Vim.FeatureRequirementsNotMet The target host does not support the virtual machine's current hardware requirements. 

But when I do a Manual migration using the GUI interface, it doesn't detect any incompatibility and VMotion works fine.

Then, why these errors are detected by powercli code? and not by GUI wizard?

How can I perform a VMotion compatibility Test like is being done using GUI that seems that is working? 

I need to perform this check for some hundreds VMs, and perform the test manually is not an option

Thanks in advance

ITSavant's profile image
ITSavant

I had to move about 40K-50K VMs around a couple years ago and looked at this, and it seems like VMware still has guardrails available to the vCenter UI that PowerCLI isn't getting. That said, you have to look at your environment and determine which incompatibility warnings you are willing to ignore and send the migration anyhow. For example a shared nothing migration is going to have many compatibility warnings, that don't mean much.

Try{$viewSI = Get-View 'ServiceInstance' -Server $SourcevCenter}Catch{}             IF($viewSI){$viewVmProvChecker = Get-View $viewSI.Content.VmProvisioningChecker -Server $SourcevCenter}             IF($viewVmProvChecker){                 $vMotionCompatibilityCheck = ""                 Try{                     $vMotionCompatibilityCheck = ($viewVmProvChecker.QueryVMotionCompatibilityEx($VMView.MoRef.ToString(), $PotentialVMhostViewTargetToValidate.MoRef))                 }Catch{                     $Passed = $False                     Write-Log -NoConsole -Level "ERROR" -Message $("EVC Mode check of Potential Source VM [$($VMView.Name)] To Potential Destination VMhost [$($PotentialVMhostViewTargetToValidate.Name)] Failed with Message, [$($Error[0].Exception)]") -FullLogFilePathName $FullLogFilePathName                 }             }             


I apologize I don't have a lot of time today to go into it, but here is quick grab of some code with a few notes I could dig up quickly, might help a bit.

            IF((($vMotionCompatibilityCheck) | ?{$_.Error}) -OR ($vMotionCompatibilityCheck)){                 #Local Storage VMs will NOT pass the Compatibility Checker, Override this specific error, but catch all others                 IF((((($vMotionCompatibilityCheck.Error.Fault.Reason.LocalizedMessage -match "Unable to access file") -AND ($vMotionCompatibilityCheck.Error.Fault.Reason.LocalizedMessage -match "local")) -AND ((($vMotionCompatibilityCheck.Error) | %{$_.GetType().Name -eq "LocalizedMethodFault"}) -Contains $True)) -AND (!($vMotionCompatibilityCheck.Error.Fault.FeatureRequirement)) -AND (!($NOTAnyOtherCompatilibilityFailureTypeIFNeedsCheckedOrLetvCenterCheckHandleIt))) -OR (!($vMotionCompatibilityCheck.Error))){                     #Only Disk Access Errors found if you get here                 }Else{                     #($vMotionCompatibiity.Error[0].Fault.FaultMessage | ?{$_.Key -eq "com.vmware.vim.vpxd.vmcheck.featureRequirementsNotMet.useClusterOrPerVmEvc"})                     #($vMotionCompatibiity.Error.Fault.FaultMessage | ?{$_.Key -match "com.vmware.vim.vmfeature.cpuid"})                     IF($vMotionCompatibilityCheck.Error.Fault.FeatureRequirement){                         $Passed = $False;                         IF((($vMotionCompatibilityCheck.Error | ?{$_.Fault -Is [VMware.Vim.FeatureRequirementsNotMet]}).Fault.FaultMessage | ?{$_.Key -eq 'com.vmware.vim.vpxd.vmcheck.featureRequirementsNotMet.useClusterOrPerVmEvc'}).Message){                             Write-Log -NoConsole -Level "ERROR" -Message $("EVC Mode check of Potential Source VM [$($VMView.Name)] To Potential Destination VMhost [$($PotentialVMhostViewTargetToValidate.Name)] Failed due to [$((($vMotionCompatibilityCheck.Error | ?{$_.Fault -Is [VMware.Vim.FeatureRequirementsNotMet]}).Fault.FaultMessage | ?{$_.Key -eq 'com.vmware.vim.vpxd.vmcheck.featureRequirementsNotMet.useClusterOrPerVmEvc'}).Message)]") -FullLogFilePathName $FullLogFilePathName                         }ElseIF((($vMotionCompatibilityCheck.Error | ?{$_.Fault -Is [VMware.Vim.FeatureRequirementsNotMet]}).Fault.FaultMessage | ?{$_.Key -Match 'com.vmware.vim.vmfeature.cpuid'})){                             Write-Log -NoConsole -Level "ERROR" -Message $("EVC Mode check of Potential Source VM [$($VMView.Name)] To Potential Destination VMhost [$($PotentialVMhostViewTargetToValidate.Name)] Failed due to [$('CPU Masks (EVC) Incompatible')]") -FullLogFilePathName $FullLogFilePathName                         }Else{                             Write-Log -NoConsole -Level "ERROR" -Message $("EVC Mode check of Potential Source VM [$($VMView.Name)] To Potential Destination VMhost [$($PotentialVMhostViewTargetToValidate.Name)] Failed due to [$('FeatureRequirementsNotMet')]") -FullLogFilePathName $FullLogFilePathName                         }                         ForEach($Line in (((($vMotionCompatibilityCheck.Error | ?{$_.Fault -Is [VMware.Vim.FeatureRequirementsNotMet]}).Fault.FaultMessage)) | Select @{'n'='FaultMessage';e={"$($_.Key) -> $($_.Message)"}})){                             Write-Log -Level "DEBUG" -Message $Line -FullLogFilePathName $FullLogFilePathName                         }                     }                     #I think this is a more general failure that is triggered by more specific falures that I need to review individually                     #IF($vMotionCompatibilityCheck.Error | ?{$_.Fault -Is [VMware.Vim.FeatureRequirementsNotMet]}){$Passed = $False; Write-Log -NoConsole -Level "ERROR" -Message $("EVC Mode check of Potential Source VM [$($VMView.Name)] To Potential Destination VMhost [$($PotentialVMhostViewTargetToValidate.Name)] Failed due to [$('FeatureRequirementsNotMet')]") -FullLogFilePathName $FullLogFilePathName}                     #https://knowledge.broadcom.com/external/article?legacyId=1003212                     <#                     [VMware.Vim.VirtualHardwareCompatibilityIssue]                     [VMware.Vim.CannotAccessVmComponent]                     [VMware.Vim.CannotAccessVmDevice]                     [VMware.Vim.VmConfigFault]                     #>                                          #                     IF($vMotionCompatibilityCheck.Error | ?{$_.Fault -Is [VMware.Vim.CpuIncompatible]}){$Passed = $False; Write-Log -NoConsole -Level "ERROR" -Message $("EVC Mode check of Potential Source VM [$($VMView.Name)] To Potential Destination VMhost [$($PotentialVMhostViewTargetToValidate.Name)] Failed due to [$('CpuIncompatible')]") -FullLogFilePathName $FullLogFilePathName}                     IF($vMotionCompatibilityCheck.Error | ?{$_.Fault -Is [VMware.Vim.CannotAccessVmConfig]}){}#Failed, Maybe, but not if Shared Nothing vMotion                     IF($vMotionCompatibilityCheck.Error | ?{$_.Fault -Is [VMware.Vim.CannotAccessVmDisk]}){}#Failed, Maybe, but not if Shared Nothing vMotion                     IF($vMotionCompatibilityCheck.Error | ?{$_.Fault -Is [VMware.Vim.CannotAccessNetwork]}){}#Failed, Maybe, but also maybe not if Shared Nothing vMotion, let Network map function dig in deeper   {$Passed = $False; Write-Log -NoConsole -Level "ERROR" -Message $("EVC Mode check of Potential Source VM [$($VMView.Name)] To Potential Destination VMhost [$($PotentialVMhostViewTargetToValidate.Name)] Failed due to [$('Missing Networks')]") -FullLogFilePathName $FullLogFilePathName}                     IF($vMotionCompatibilityCheck.Error){                         ForEach($ErrorItem in ($vMotionCompatibilityCheck.Error | ?{$_.Fault -IsNot [VMware.Vim.FeatureRequirementsNotMet]} | ?{$_.Fault -IsNot [VMware.Vim.CpuIncompatible]} | ?{$_.Fault -IsNot [VMware.Vim.CannotAccessVmConfig]} | ?{$_.Fault -IsNot [VMware.Vim.CannotAccessVmDisk]})){                             # $ErrorItem = ($vMotionCompatibilityCheck.Error | ?{$_.Fault -IsNot [VMware.Vim.FeatureRequirementsNotMet]} | ?{$_.Fault -IsNot [VMware.Vim.CpuIncompatible]} | ?{$_.Fault -IsNot [VMware.Vim.CannotAccessVmConfig]} | ?{$_.Fault -IsNot [VMware.Vim.CannotAccessVmDisk]})[0]                             #$Message = "Fault [$($ErrorItem.Fault.Reason.Fault)], Meaasge [$($ErrorItem.Fault.Reason.LocalizedMessage)]"                             #$Message = "Fault [$($ErrorItem.Fault.GetType().Name)], Meaasge [$($ErrorItem.Error.LocalizedMessage)]"                             #$Message = "Fault [$($ErrorItem.Fault.GetType().Name)], Meaasge [$($ErrorItem.LocalizedMessage)]"                             $Message = "EVC Check Error Meaasge [$($ErrorItem.LocalizedMessage)]"                             #$Message                             Write-Log -Level "DEBUG" -Message $Message -FullLogFilePathName $FullLogFilePathName                         }                     }                 }             }
alpatio's profile image
alpatio

Hi,

ITSavant. Thanks for the code. I don't know how to answer correctly Then I'm answering using my own question..

I've also found these articles 

https://blogs.vmware.com/PowerCLI/2014/03/evc-powercli-5-5-r2part-2.html

VMware EVC and CPU Compatibility FAQ

Enhanced vMotion Compatibility (EVC) processor support

And If I understand how EVC WORKS, then I only need to check if the current EVC machine is lower or Equal than the destination EVC host/cluster. 

A higher EVC level should support lower ones.

Then at least on my case,  for CPU compatibility I will only check if VM EVC is supported  into the destination EVC cluster, for mee seems that is more simple than checking lots of possibilities checking all the possible warnings related with CPU.

I've tested code that this based on the Blog script,  

$viServer = $Global:DefaultViserver

$dstclustername = 'DestinationCluster'
$dstcluster = get-cluster $dstclustername
$clusterEVC= $dstcluster.EVCMode

# filter EVC Modes for Intel vendor
$availableEVCModes = $viServer.ExtensionData.Capability.SupportedEVCMode | where {$_.vendor -eq 'intel'}

# Fill hash, to quick retrieve and compare Tier value later

$EVCModes=@{}
$availableEVCModes | %{$EVCModes.$($_.Key) = $_.VendorTier}

$vm = get-vm 'TESTvmEVC' # Note must be powered on

$vmEVC = $vm.ExtensionData.Runtime.MinRequiredEVCModeKey

if ($EVCModes[$vmEVC] -le $EVCModes[$clusterEVC]) {
   write-warning 'OK EVC Compatible'

} else {
  write-warning 'NOT EVC compatible!!!!'
}

ITSavant's profile image
ITSavant

You are confusing 2 different things EVC compatibility with vMotion compatibility, while related vMotion compatibility INCLUDES EVC (cpu features really) compatibility, but also checks a lot of other things, like do networks with matching names/vlans exist, disk capacity, available cpu & memory capacity, etc. So while checking the EVC mode is a great start, (and maybe all you need if all the other pieces are good), it is not a generally reliable way to pre-validate a successful vMotion.