This isn't a question, so much as pointing out a current issue with Get-VM. Depending on how you use it to query VM objects (by name only or by location (via pipeline or -Location <object>), you get a different object type. (Note that this only applies to VMs. I didn't observe the same type of issue with other objects, such as VMHosts or Clusters.)
The following was done using VMware.VimAutomation.Core 12.6.0.19601570 on vCenter 7.0.3:
> $VMObjs = Get-VM -Server $VIConnection
> $VMObjs[0].GetType().Name
UniversalVirtualMachineImpl
> $VMObjs[0] | Get-Member
TypeName: VMware.VimAutomation.ViCore.Impl.V1.VM.UniversalVirtualMachineImpl
<snip>
> $VMObjs = Get-VM -Server $VIConnection -Location (Get-VMHost -Server $VIConnection)
> $VMObjs[0].GetType().Name
VirtualMachineImpl
> $VMObjs[0] | Get-Member
TypeName: VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl
<snip>
> $VMObjs = Get-VMHost -Server $VIConnection | Get-VM
> $VMObjs[0].GetType().Name
VirtualMachineImpl
> $VMObjs[0] | Get-Member
TypeName: VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl
<snip>
As such, I would suggest that anyone writing a function that requires a -VM parameter save themselves some frustration and do something like this:
param (
[Parameter (
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Mandatory = $true
)]
[ValidateScript(
{
$_.GetType().Name -in "VirtualMachineImpl", "UniversalVirtualMachineImpl"
}
)]
[ValidateNotNullOrEmpty()]
[Object[]]$VM
)