windowsvagrantvagrant-windows

Provisioning Windows VM with Vagrant cannot execute remote WinRM commands


I'm trying to install some basic tools on an existing Vagrant box, but my shell commands fail because Vagrant cannot execute WinRM commands.

I get the following output:

❯ vagrant up --provider vmware_workstation
Bringing machine 'default' up with 'vmware_workstation' provider...
==> default: Cloning VMware VM: 'StefanScherer/windows_2019'. This can take some time...
==> default: Verifying vmnet devices are healthy...
==> default: Preparing network adapters...
==> default: Fixed port collision for 3389 => 3389. Now on port 2200.
==> default: Starting the VMware VM...
==> default: Waiting for the VM to receive an address...
==> default: Forwarding ports...
    default: -- 3389 => 2200
    default: -- 5985 => 55985
    default: -- 5986 => 55986
    default: -- 22 => 2222
==> default: Waiting for machine to boot. This may take a few minutes...
    default: WinRM address: 127.0.0.1:55985
    default: WinRM username: vagrant
    default: WinRM execution_time_limit: PT2H
    default: WinRM transport: negotiate
An error occurred executing a remote WinRM command.

Shell: Cmd
Command: hostname
Message: [WSMAN ERROR CODE: 2147942421]: <f:WSManFault Code='2147942421' Machine='127.0.0.1' xmlns:f='http://schemas.microsoft.com/wbem/wsman/1/wsmanfault'><f:Message><f:ProviderFault path='%systemroot%\system32\winrscmd.dll' provider='Shell cmd plugin'>The device is not ready. </f:ProviderFault></f:Message></f:WSManFault>

When I have a look at the VM it has the "do you want to trust this network" pop-up open. When I follow the process and accept the prompt the provisioning continues as expected, but I don't really want to stay put waiting for Windows to come up to click a button. Is there a way to automate this?

This is the Vagrantfile I'm using:

Vagrant.configure("2") do |config|
  config.vm.box = "StefanScherer/windows_2019"

  # Setup environment.
  config.vm.provision "shell", path: "provision.ps1"
  # PowerShell must be reloaded, so we'll open up a new instance.
  config.vm.provision "shell", inline: "choco feature enable -n allowGlobalConfirmation"
  config.vm.provision "shell", inline: "choco install firefox azure-cli terraform"

  config.vm.provider "vmware_workstation" do |v|
    v.gui = true
  end
end

Solution

  • Nevermind. After some more testing I discovered that I just had to increase the number of retries for WinRM connections in the Vagrantfile:

    config.winrm.max_tries = 300 # default is 20
    config.winrm.retry_delay = 2 #seconds. This is the defaul value and just here for documentation.
    

    This sets the timeout to 10 minutes which on my machine is more than enough to boot up a Windows VM. The default of 40s however is often not enough and would only sometimes provision my VM correctly.

    Hope this helps anyone.