Skip to content

Hyper-V provider fails admin check under PowerShell CLM (Constrained Language Mode) #13775

@granstrand

Description

@granstrand

When using Vagrant to manage Hyper-V guests on Windows hosts, even with
Windows Terminal running as administrator (run as admin), Vagrant still
complains that it is not running with administrative privileges.

Expand for PowerShell prompt
PS D:\vm\vw11> net session >$null 2>&1; if($LASTEXITCODE){'not admin'}else{'admin'}
admin
PS D:\vm\vw11> vagrant up --provider=hyperv
The provider 'hyperv' that was requested to back the machine
'default' is reporting that it isn't usable on this system. The
reason is shown below:

The Hyper-V provider requires that Vagrant be run with
administrative privileges. This is a limitation of Hyper-V itself.
Hyper-V requires administrative privileges for management
commands. Please restart your console with administrative
privileges and try again.
PS D:\vm\vw11>

After checking the debug log, it appears that Windows security measures are
causing Vagrant's Hyper-V provider to malfunction -- our Info Security and IT
department mandates that PowerShell runs under Constrained Language Mode
(CLM) due to cybersecurity concerns.

Several existing issues are potentially relevant:


Debug output

In the debug output, we can see that three basic checks Vagrant performs to
verify Hyper-V availability have failed, presumably because PowerShell lacks
the necessary capabilities under CLM.

(new-object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent())
 ).IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
Write-Output ([System.Security.Principal.WindowsIdentity]::GetCurrent().Groups | Select-Object Value | ConvertTo-JSON)
$x = (Get-VMHost).Name; if($x -eq [System.Net.Dns]::GetHostName()){ Write-Output 'true'}
Relevant debug log section
INFO environment: Getting machine: default (hyperv)
INFO environment: Uncached load of machine.
DEBUG powershell: preferred powershell executable name: pwsh
DEBUG powershell: detected powershell for "pwsh" - C:\Program Files\PowerShell\7/pwsh.EXE
DEBUG powershell: detected powershell for "powershell" - C:\WINDOWS\System32\WindowsPowerShell\v1.0\/powershell.EXE
DEBUG powershell: using preferred powershell "pwsh" - C:\Program Files\PowerShell\7/pwsh.EXE
INFO subprocess: Starting process: ["C:\\Program Files\\PowerShell\\7/pwsh.EXE", "-NoLogo", "-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-Command", "Write-Output $PSVersionTable.PSVersion.Major"]
INFO subprocess: Command not in installer, restoring original environment...
DEBUG subprocess: Selecting on IO
DEBUG subprocess: Waiting for process to exit. Remaining to timeout: 29
DEBUG subprocess: Exit status: 0
INFO subprocess: Starting process: ["C:\\Program Files\\PowerShell\\7/pwsh.EXE", "-NoLogo", "-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-Command", "(new-object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)"]
INFO subprocess: Command not in installer, restoring original environment...
DEBUG subprocess: Selecting on IO
DEBUG subprocess: Waiting for process to exit. Remaining to timeout: 32000
DEBUG subprocess: Exit status: 1
INFO subprocess: Starting process: ["C:\\Program Files\\PowerShell\\7/pwsh.EXE", "-NoLogo", "-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-Command", "Write-Output ([System.Security.Principal.WindowsIdentity]::GetCurrent().Groups | Select-Object Value | ConvertTo-JSON)"]
INFO subprocess: Command not in installer, restoring original environment...
DEBUG subprocess: Selecting on IO
DEBUG subprocess: Waiting for process to exit. Remaining to timeout: 32000
DEBUG subprocess: Exit status: 1
INFO subprocess: Starting process: ["C:\\Program Files\\PowerShell\\7/pwsh.EXE", "-NoLogo", "-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-Command", "$x = (Get-VMHost).Name; if($x -eq [System.Net.Dns]::GetHostName()){ Write-Output 'true'}"]
INFO subprocess: Command not in installer, restoring original environment...
DEBUG subprocess: Selecting on IO
DEBUG subprocess: Waiting for process to exit. Remaining to timeout: 32000
DEBUG subprocess: Exit status: 1
INFO environment: Running hook: environment_unload

Expected behavior

  • Expect Vagrant Hyper-V provider to correctly tell it's run as admin.

Actual behavior

  • Vagrant Hyper-V provider refuse to run even when the console is already running with administrative privileges.

Reproduction information

Vagrant version

  • Vagrant 2.4.9
    • Installed via winget

Host operating system

  • Windows 11 x64 24H2
    • Microsoft Windows NT 10.0.26100.0

Guest operating system

  • Windows 11 x64 25H2
    • gusztavvargadr/windows-11-25h2-enterprise

Steps to reproduce

  1. Enable Hyper-V with Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
  2. Reboot host machine if needed.
  3. Install latest Vagrant with winget: winget install --source winget vagrant
  4. Launch a new Windows Terminal window as administrator.
  5. Create a folder and put Vagrantfile into it
    mkdir D:\vm\vw11
    mv Vagrantfile D:\vm\vw11
    
  6. Run vagrant up --provider=hyperv

Vagrantfile

Expand for Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "gusztavvargadr/windows-11-25h2-enterprise"
  config.vm.box_version = "2511.0.0"
  config.vm.communicator = "winrm"
  config.vm.boot_timeout = 600
  config.vm.provider "hyperv" do |h|
    h.cpus = 4
    h.memory = 8192
    h.enable_virtualization_extensions = true # nested virtualization
    h.linked_clone = true  # save host space and speed up deployment
  end

  # config.vm.provision "shell", path: "scripts/setup-dev-env.ps1"
  # the ps1 currently only contains `winget source update`
end

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions