Skip to content

Instantly share code, notes, and snippets.

@andrealbinop
Last active May 28, 2023 01:54
Show Gist options
  • Save andrealbinop/57e388df5e881937e62a to your computer and use it in GitHub Desktop.
Save andrealbinop/57e388df5e881937e62a to your computer and use it in GitHub Desktop.
Setup modern.ie vagrant boxes

Setup modern.ie vagrant boxes

Since modern.ie released vagrant boxes, it' no longer necessary to manually import the ova file to virtualbox, as mentioned here.

However, the guys at modern.ie didn't configured the box to work with WinRM. This how-to addresses that, presenting steps to proper repackage these boxes, adding WinRM support. Additionally configures chocolatey package manager and puppet provisioner.

Pre-requisites

The host machine must have Vagrant and VirtualBox installed.

1. Configure the Vagrantfile

The same Vagrantfile can be used with different versions of modern.ie available boxes. Read the comments in the file for details.

# -*- mode: ruby -*-
# vi: set ft=ruby :

# box name into env var, same script can be used with different boxes. Defaults to win7-ie11.
box_name = box_name = ENV['box_name'] != nil ? ENV['box_name'].strip : 'win7-ie11'
# box repo into env var, so private repos/cache can be used. Defaults to http://aka.ms
box_repo = ENV['box_repo'] != nil ? ENV['box_repo'].strip : 'http://aka.ms'

Vagrant.configure("2") do |config|
  # If the box is win7-ie11, the convention for the box name is modern.ie/win7-ie11
  config.vm.box = "modern.ie/" + box_name
  # If the box is win7-ie11, the convention for the box url is http://aka.ms/vagrant-win7-ie11
  config.vm.box_url = box_repo + "/vagrant-" + box_name
  # big timeout since windows boot is very slow
  config.vm.boot_timeout = 500

  # rdp forward
  config.vm.network "forwarded_port", guest: 3389, host: 3389, id: "rdp", auto_correct: true

  # winrm config, uses modern.ie default user/password. If other credentials are used must be changed here
  config.vm.communicator = "winrm"
  config.winrm.username = "IEUser"
  config.winrm.password = "Passw0rd!"

  config.vm.provider "virtualbox" do |vb|
    # first setup requires gui to be enabled so scripts can be executed in virtualbox guest screen
    #vb.gui = true
    vb.customize ["modifyvm", :id, "--memory", "1024"]
    vb.customize ["modifyvm", :id, "--vram", "128"]
    vb.customize ["modifyvm", :id,  "--cpus", "2"]
    vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
    vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
    vb.customize ["guestproperty", "set", :id, "/VirtualBox/GuestAdd/VBoxService/--timesync-set-threshold", 10000]
  end
end

2. Setup

Create a directory and a Vagrantfile file with the contents from previous section. For the first run, uncomment the vb.gui=true line to disable VirtualBox headless mode. Start the box running the command:

# uncomment below to change the box version and repo
# export box_name=win7-ie11 && export box_repo=http://aka.ms
$ vagrant up

When the machine is booted, do the following steps on VirtualBox guest window:

@echo off
set WINRM_EXEC=call %SYSTEMROOT%\System32\winrm
%WINRM_EXEC% quickconfig -q
%WINRM_EXEC% set winrm/config/winrs @{MaxMemoryPerShellMB="300"}
%WINRM_EXEC% set winrm/config @{MaxTimeoutms="1800000"}
%WINRM_EXEC% set winrm/config/client/auth @{Basic="true"}
%WINRM_EXEC% set winrm/config/service @{AllowUnencrypted="true"}
%WINRM_EXEC% set winrm/config/service/auth @{Basic="true"}
  • At this time the up command will be probably verifying if the guest booted properly. Since you just configured WinRM, the command should terminate successfully.

3. Chocolatey and Puppet

Run the following script to configure chocolatey and puppet on the guest machine:

@echo off
@powershell -NoProfile -ExecutionPolicy unrestricted -Command "iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin
choco install -y puppet

4. Package

Since there's a lot of Windows specific configuration, you can include the Vagrantfile in the package command so winrm and virtualbox configuration get's default values when the repackaged is used for other purposes. Remember to run the command in the same directory the Vagrantfile resides:

$ vagrant package --output "yourboxname" --Vagrantfile Vagrantfile

After that you're all set!

@dragon788
Copy link

I had to add a couple lines and install a package to make this work under Linux.

# Need the WinRM gem for managing from Linux
$ sudo gem install winrm

    config.vm.communicator = "winrm"
+  config.winrm.host = "localhost"
    config.winrm.username = "IEUser"
    config.winrm.password = "Passw0rd!"
# This one may not be necessary, I added it for completeness
+  config.vm.guest = :windows

# In order to USE the two CPUs you need the ioapic
# Virtualbox gives an error in the GUI and only shows 1 CPU in the VM otherwise
      vb.customize ["modifyvm", :id, "--cpus", "2"]
+    vb.customize ["modifyvm", :id, "--ioapic", "on"]
# We had to modify the network range because we are running Virtualbox inside VMware
+    vb.customize ["modifyvm", :id, "--natnet1", "192.168.199.0/24"]

@vmarkovtsev
Copy link

Please note that the script which setups WinRM must be run after each machine reboot. To run it with administrator rights, use Task Scheduler.

@johnjelinek
Copy link

@vmarkovtsev: why does it need to be run on each reboot? I've been able to vagrant reload and vagrant halt && vagrant up and it boots fine without needing to re-run the WinRM script.

@molant
Copy link

molant commented Oct 6, 2015

@andreptb WinRM should be installed in 10, 8.1 and 8.0 machines. If this is not the case please let me know. I'm available via GitHub or Twitter (same username) or @MSEdgeDev.

@torquemad
Copy link

For me, Vagrant hangs when firing up the winrm shell:
==> default: Resuming suspended VM...
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
default: WinRM address: localhost:5985
default: WinRM username: IEUser
default: WinRM transport: plaintext

debug output:
if ($?) { exit 0 } else { if($LASTEXITCODE) { exit $LASTEXITCODE } else { exit 1 } }
INFO winrmshell: Attempting to connect to WinRM...
INFO winrmshell: - Host: 127.0.0.1
INFO winrmshell: - Port: 55985
INFO winrmshell: - Username: IEUser
INFO winrmshell: - Transport: plaintext

If anyone else had this issue, please let me know your solution :)

@lhotari
Copy link

lhotari commented Nov 23, 2015

The WinRM setup didn't work for me. This worked:

winrm quickconfig -q
@powershell -NoProfile -ExecutionPolicy Bypass -Command "Set-Item WSMan:\localhost\Service\AllowUnencrypted -Value True; Set-Item WSMan:\localhost\Service\Auth\Basic -Value True"
sc triggerinfo winrm start/networkon stop/networkoff

@e3e6
Copy link

e3e6 commented Feb 23, 2016

Is it possible to make this script use the *.box file placed next to Vagrantfile instead of downloading from the aka.ms?

@ryx
Copy link

ryx commented Mar 15, 2016

@e3e6: Vagrant supports file:// URLs for the box_url setting. E.g. export box_name=mybox.box && export box_repo=file:///path/to/your/box/ && vagrant up". Though I'd recommend adjusting the Vagrantfile to your needs.

@chetanagrawal
Copy link

Also, after repackaging, WinRM is not already configured.
I am using VirtualBox on Windows7 and using Windows7 IE11 box.

@cdaringe
Copy link

cdaringe commented Jul 1, 2016

On vagrant up ... nothing happens for me. On subsequent vagrant ups it warns that its already been provisioned. I did uncommente .gui. hmmm. Any tips? Thanks!

@rquadling
Copy link

Are the boxes downloaded from http://aka.ms the same as those from https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/

@darkn3rd
Copy link

Is there one for MSEdge on Win10?

@iAnomaly
Copy link

iAnomaly commented Sep 21, 2016

@molant Unless I am misunderstanding you, I am not seeing the expected behavior you describe for Edge Windows 10 (and possibly all the other versions) downloaded from here: https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/

Looks like there are two issues:

  1. The VirtualBox network adapter isn't recognized and the out of the box Network List Management Policies (in Local Security Policy) Location type is Not configured. It appears this needs to be Private in order for WinRM to work without manual human intervention. User permissions is also Not configured and this should probably be User can change location or even User cannot change location to force the Private location and ensure WinRM stays operational.
  2. I still had to run winrm quickconfig -q manually the first time to start the WinRM service and open the Windows firewall ports. I'm not sure if this would still be true if issue #1 above was resolved.

I'm not sure if that's what you meant by "...installed in 10, 8.1 and 8.0 machines.", but it would be so much more helpful if both of the issues above worked out of the box so vagrant up worked with WinRM the first time without any manual human intervention inside the VM. The ideal workflow would be to just download the image and run Vagrant configured with the WinRM communicator and have all else work; no manual intervention required!

Thanks for your time,
Cameron

@danielmenezesbr
Copy link

Guys...
I created a Vagrantfile able to change network location and activate WinRM automatically during the "vagrant provision".

See https://github.com/danielmenezesbr/modernie-winrm for more details.

@jonashackt
Copy link

Hmm, seems to be that the problem is a mix of all answers. WinRM is already installed and configured on the current boxes from https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/ - the only thing, that´s not configured right are the Network List Management Policies, like @iAnomaly stated.

So for now you need to manually boot the VM with getting the timeout error, go into Local Security Policy / Network List Management Policies, double klick on Network, go to tab Network Location and set the Location type to private and the User permissions to User can change location. That´s all, now assuming a correct Vagrantfile with WinRM configuration, the vagrant up will work without any errors.

@CoolBalance
Copy link

Setting the policies as jonashackt notes works for me. I am unable to run the shell provisioner as it fails. I'm using the Windows10 box from microsoft-edge. vagrant up is fine, just no provisioning. (Ubuntu 16.10 host, Vagrant 1.9.1)

@jonashackt
Copy link

jonashackt commented Feb 10, 2017

@CoolBalance - same for me, vagrant up works, but the provisioners fail:

$ vagrant provision
==> default: Running provisioner: shell...
/opt/vagrant/embedded/gems/gems/winrm-fs-0.3.2/lib/winrm-fs/core/file_transporter.rb:378:in `parse_response': [WinRM::FS::Core::FileTransporter] Upload failed (exitcode: 0), but stderr present (WinRM::FS::Core::FileTransporterFailed)
	from /opt/vagrant/embedded/gems/gems/winrm-fs-0.3.2/lib/winrm-fs/core/file_transporter.rb:192:in `check_files'
	from /opt/vagrant/embedded/gems/gems/winrm-fs-0.3.2/lib/winrm-fs/core/file_transporter.rb:80:in `block in upload'
	from /opt/vagrant/embedded/lib/ruby/2.2.0/benchmark.rb:288:in `measure'
	from /opt/vagrant/embedded/gems/gems/winrm-fs-0.3.2/lib/winrm-fs/core/file_transporter.rb:78:in `upload'
	from /opt/vagrant/embedded/gems/gems/winrm-fs-0.3.2/lib/winrm-fs/file_manager.rb:112:in `block in upload'
	from /opt/vagrant/embedded/gems/gems/winrm-1.8.1/lib/winrm/winrm_service.rb:363:in `create_executor'
	from /opt/vagrant/embedded/gems/gems/winrm-fs-0.3.2/lib/winrm-fs/file_manager.rb:110:in `upload'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/plugins/communicators/winrm/shell.rb:80:in `upload'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/plugins/communicators/winrm/communicator.rb:173:in `upload'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/plugins/provisioners/shell/provisioner.rb:114:in `block (2 levels) in provision_winrm'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/plugins/provisioners/shell/provisioner.rb:105:in `tap'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/plugins/provisioners/shell/provisioner.rb:105:in `block in provision_winrm'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/plugins/provisioners/shell/provisioner.rb:225:in `with_script_file'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/plugins/provisioners/shell/provisioner.rb:104:in `provision_winrm'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/plugins/provisioners/shell/provisioner.rb:22:in `provision'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/builtin/provision.rb:133:in `run_provisioner'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/warden.rb:95:in `call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/warden.rb:95:in `block in finalize_action'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/warden.rb:34:in `call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/warden.rb:34:in `call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/builder.rb:116:in `call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/runner.rb:66:in `block in run'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/util/busy.rb:19:in `busy'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/runner.rb:66:in `run'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/environment.rb:479:in `hook'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/builtin/provision.rb:121:in `call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/builtin/provision.rb:121:in `block in call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/builtin/provision.rb:103:in `each'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/builtin/provision.rb:103:in `call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/warden.rb:34:in `call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/plugins/providers/virtualbox/action/check_accessible.rb:18:in `call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/warden.rb:34:in `call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/warden.rb:95:in `block in finalize_action'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/warden.rb:34:in `call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/warden.rb:34:in `call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/builder.rb:116:in `call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/runner.rb:66:in `block in run'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/util/busy.rb:19:in `busy'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/runner.rb:66:in `run'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/builtin/call.rb:53:in `call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/warden.rb:34:in `call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/warden.rb:95:in `block in finalize_action'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/warden.rb:34:in `call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/warden.rb:34:in `call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/builder.rb:116:in `call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/runner.rb:66:in `block in run'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/util/busy.rb:19:in `busy'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/runner.rb:66:in `run'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/builtin/call.rb:53:in `call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/warden.rb:34:in `call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/builtin/config_validate.rb:25:in `call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/warden.rb:34:in `call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/plugins/providers/virtualbox/action/check_virtualbox.rb:17:in `call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/warden.rb:34:in `call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/builder.rb:116:in `call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/runner.rb:66:in `block in run'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/util/busy.rb:19:in `busy'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/action/runner.rb:66:in `run'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/machine.rb:225:in `action_raw'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/machine.rb:200:in `block in action'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/environment.rb:567:in `lock'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/machine.rb:186:in `call'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/machine.rb:186:in `action'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/plugins/commands/provision/command.rb:30:in `block in execute'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/plugin/v2/command.rb:235:in `block in with_target_vms'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/plugin/v2/command.rb:229:in `each'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/plugin/v2/command.rb:229:in `with_target_vms'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/plugins/commands/provision/command.rb:29:in `execute'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/cli.rb:42:in `execute'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/lib/vagrant/environment.rb:308:in `cli'
	from /opt/vagrant/embedded/gems/gems/vagrant-1.9.1/bin/vagrant:127:in `<main>'

@snfnwgi
Copy link

snfnwgi commented Sep 24, 2017

@snfnwgi
Copy link

snfnwgi commented Sep 30, 2017

How do I solve the synchronization problem? I want to use NFS or RSYNC, but error

@jmhublar
Copy link

jmhublar commented Oct 8, 2017

Get-NetConnectionProfile
Which lists the profiles and from which you need to find the index number

Set-NetConnectionProfile -InterfaceIndex 1 -NetworkCategory Private
Where 1 is the index number of the profile to change so may be something other than 1

@hazmeister
Copy link

WinRM seems to start on a delay by default, run this as admin to get it to start when the machine does.
sc config winrm start= auto

@clement-igonet
Copy link

clement-igonet commented Feb 9, 2018

To activate winrm (work on win10 modern.ie machine):

# (...)
  config.vm.communicator = ENV['communicator'] || 'winrm'
  config.ssh.username = "IEUser"
  config.ssh.password = "Passw0rd!"
  config.ssh.insert_key = false
  config.ssh.sudo_command = ''
# (...)
  config.ssh.shell = 'sh -l'
    config.vm.provision "shell",
      binary: true,
      privileged: false,
      inline: <<-SHELL
      # winrm - Switch to private network
      /cygdrive/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe -InputFormat None -NoProfile -ExecutionPolicy Bypass -Command '$networkListManager = [Activator]::CreateInstance([Type]::GetTypeFromCLSID([Guid]"{DCB00C01-570F-4A9B-8D69-199FDBA5723B}")) ; $connections = $networkListManager.GetNetworkConnections() ; $connections | % {$_.GetNetwork().SetCategory(1)}'
    SHELL
# (...)

And then, at first boot:

$ communicator=ssh vagrant up

@clement-igonet
Copy link

When connecting to win7 modern.ie machine with vagrant/ssh (net-ssh ruby lib) and using "sh" shell and IEUser/Passw0rd!, whoami return "sshd_server".
When connecting directly with openssh clent, it returns "ieuser".
The issue it creates is bad right access to setup winrm. Anybody already met the same issue?

@xywang68
Copy link

@clement-igonet, on Windows-10 your above "activate winrm" instruction works great.

@rzapletal
Copy link

Is it still working for you? Newest vagrant and VirtualBox, freshly downloaded Windows 10 box and I still get only PowerShell error.

powershell.exe : Cannot convert the "DCB00C01-570F-4A9B-8D69-199FDBA5723B" value of type
    + CategoryInfo          : NotSpecified: (Cannot convert ... value of type :String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError
"System.Management.Automation.ScriptBlock" to type "System.Guid".
At line:1 char:1
+ $networkListManager = [Activator]::CreateInstance([Type]::GetTypeFrom ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [], RuntimeException
    + FullyQualifiedErrorId : ConvertToFinalInvalidCastException

You cannot call a method on a null-valued expression.
At line:1 char:125
+ ... A5723B})) ; $connections = $networkListManager.GetNetworkConnections( ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

You cannot call a method on a null-valued expression.
At line:1 char:204
+ ... workConnections() ; $connections | % {$_.GetNetwork().SetCategory(1)}
+                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment