#13841·vagrant

Hyper-V provider fails under PowerShell 7 due to duplicate `VirtualMachine` CLR types

Author: OnceUponALoopCreated Sep 3, 2026Updated Sep 3, 2026
Labelswaiting-intake

Debug output

Failed to configure CPUs: Cannot process argument transformation on parameter 'VM'.
Cannot convert the "VirtualMachine (...)" value of type
"Microsoft.HyperV.PowerShell.VirtualMachine" to type
"Microsoft.HyperV.PowerShell.VirtualMachine".

The debug log confirms Vagrant selected PowerShell 7.6.5:

preferred powershell executable name: pwsh
using preferred powershell "pwsh" - ...\pwsh.EXE

Expected behavior

The Hyper-V provider should configure and start the VM when Vagrant selects a supported PowerShell 7 installation.

Actual behavior

Vagrant selects pwsh by default, imports the VM, then fails in configure_vm.ps1 while calling Set-VagrantVMCPUS.

PowerShell 7 resolves Vagrant’s typed $VM parameter and the object returned by Hyper-V\Get-VM from different assemblies:

Get-VM runtime object:
Microsoft.HyperV.PowerShell.VirtualMachine
Microsoft.HyperV.PowerShell.Objects.dll

Set-VagrantVMCPUS parameter:
Microsoft.HyperV.PowerShell.VirtualMachine
Microsoft.HyperV.PowerShell.dll

These are different CLR types despite having identical full names. Windows native Hyper-V cmdlets use Microsoft.HyperV.PowerShell.Objects.dll; the conflicting conversion is introduced by the wrapper annotation in vagrant.

Setting the following makes the same vagrant up succeed:

$env:VAGRANT_PREFERRED_POWERSHELL = "powershell"

Reproduction information

Vagrant version

Vagrant 2.4.9

Host operating system

Microsoft Windows 11 Enterprise
Version 10.0.22631
64-bit
PowerShell Core 7.6.5
Windows PowerShell 5.1
Hyper-V enabled

Guest operating system

Red Hat Enterprise Linux 9.2

This is a host-side VM configuration failure, before guest boot so it's not guest-specific and will also occur if the guest was Windows.

Steps to reproduce

  1. Install PowerShell 7 alongside Windows PowerShell and enable Hyper-V.
  2. Ensure VAGRANT_PREFERRED_POWERSHELL is unset.
  3. Use the minimal Vagrantfile below.
  4. Run:
Remove-Item Env:\VAGRANT_PREFERRED_POWERSHELL -ErrorAction SilentlyContinue
vagrant destroy -f
vagrant up --provider hyperv --debug
  1. Observe the error
Failed to configure CPUs: Cannot process argument transformation on parameter 'VM'.
Cannot convert the "VirtualMachine (...)" value of type
"Microsoft.HyperV.PowerShell.VirtualMachine" to type
"Microsoft.HyperV.PowerShell.VirtualMachine".
  1. Repeat using Windows PowerShell:
$env:VAGRANT_PREFERRED_POWERSHELL = "powershell"
vagrant destroy -f
vagrant up --provider hyperv
  1. Observe that VM configuration succeeds.

Manual Reproduction

We can observe the same failure manually

Import-Module Hyper-V -Force

$module = "<VAGRANT_INSTALL>\embedded\gems\gems\vagrant-2.4.9\" +
    "plugins\providers\hyperv\scripts\\\utils\VagrantVM\VagrantVM.psm1"

Import-Module $module -Force

$vm = Hyper-V\Get-VM | Select-Object -First 1

$vm.GetType().AssemblyQualifiedName
(Get-Command Set-VagrantVMCPUS).
    Parameters["VM"].ParameterType.AssemblyQualifiedName

# CPUCount is omitted; this exercises binding without modifying the VM.
Set-VagrantVMCPUS -VM $vm

Under pwsh.exe this fails with the duplicate-type conversion error. Under powershell.exe it succeeds.

Vagrantfile

Vagrant.configure("2") do |config|
  config.vm.box = "generic/rocky9"
  config.vm.provider "hyperv" do |hyperv|
    hyperv.cpus = 1
  end
end

Root cause

VagrantVM.psm1 declares $VM as:

[Microsoft.HyperV.PowerShell.VirtualMachine] $VM

Under PowerShell 7, that annotation resolves from Microsoft.HyperV.PowerShell.dll, while Hyper-V\Get-VM returns the type from Microsoft.HyperV.PowerShell.Objects.dll.

The annotation appears in:

Set-VagrantVMMemory
Set-VagrantVMCPUS
Set-VagrantVMVirtExtensions
Set-VagrantVMAutoActions
Set-VagrantVMService
Set-VagrantVMSwitch

Vagrant prefers pwsh over powershell and only checks executable availability and min/major version, this incompatibility becomes forced.

Workaround

Force vagrant to use powershell (PowerShell 5.1) and not pwsh (PowerShell 7)

$env:VAGRANT_PREFERRED_POWERSHELL = "powershell"

Solution

Fix the Hyper-V type in all six wrapper functions.

We can use PSType which checks that the object passed is the expected type name but doesn't attempt a CLR conversion (which triggers the wrong assembly selection).

ex. in plugins\providers\hyperv\scripts\\\utils\VagrantVM\VagrantVM.psm1, modify Set-VagrantVMCPUS

function Set-VagrantVMCPUS {
    param (
        [Parameter(Mandatory = $true)]
        [ValidateNotNull()]
        [PSTypeName("Microsoft.HyperV.PowerShell.VirtualMachine")]
        $VM,

        [Parameter(Mandatory = $false)]
        [int] $CPUCount
    )

    if ($CPUCount) {
        Hyper-V\Set-VM -VM $VM -ProcessorCount $CPUCount
    }

    return $VM
}

and do it for the rest

Set-VagrantVMMemory
Set-VagrantVMCPUS
Set-VagrantVMVirtExtensions
Set-VagrantVMAutoActions
Set-VagrantVMService
Set-VagrantVMSwitch

Or just stop passing objects and use the VM ID instead, but that's a bigger change

function Set-VagrantVMCPUS {
    param (
        [Parameter(Mandatory = $true)]
        [Guid] $VMID,

        [int] $CPUCount
    )

    $vm = Hyper-V\Get-VM -Id $VMID -ErrorAction Stop
    Hyper-V\Set-VM -VM $vm -ProcessorCount $CPUCount
}