Introduction

There are many examples online on how to create a Linux Vagrant Box including mine. But not so much around Windows boxes.

The easiest way? Just shop around in Vagrant Cloud, identify a Windows box, and spin it using Vagrant Up. That’s exactly what I did but I faced a problem after the trial period expired as I couldn’t even license it using a product key. In this blog, we will showcase how to create a Vagrant box based on Windows 10 Pro that you can activate if you have a license.

vagrant

 

Why create a Window Virtual Machine inside a PC laptop

  • My VPN cuts all internet access!

    My team has recently been provided VPN links to a client’s environment that cuts internet access and this made us think of a workaround to isolate that network within a VirtualBox VM which worked like a charm. To make it even faster to spin as the team grew, I decided to find Vagrant boxes in Vagrant Cloud and shared the Vagrantfile with my colleagues.

     

  • What happens when the Windows evaluation period ends?

    As soon as these evaluation-based Vagrant boxes expired, the VMs started to shut down every hour or so, which put one’s work at risk. You don’t want your OS to shut off in the middle of a migration task! We even bought license keys but the VMs couldn’t get activated.

     

    windows

  • Vagrant Box version after another, l still faced the same issue when trying to license it.
    The bottom line is those Vagrant Boxes had an evaluation-only license and were not licensed to activate the software permanently.

Solution: Create a new Vagrant Box from scratch  

Note: all commands below were run in PowerShell and can be gathered in a single script. 

STEPS

  1. Create a Virtual Box Virtual Machine

  2. Install Windows on the Virtual Machine

  3. Configure Windows for Vagrant

  4. Package and Export the box through Vagrant

CREATE THE VIRTUAL MACHINE

Create a new Windows 10 Virtual Machine using official ISO from Microsoft (Media Creation Tool)

  • Choose low disk size (30) + lowest memory (1.5GB) +1 CPU

  • Other VirtualBox settings

    • Settings > Advanced: Enable bidirectional shared clipboard and drag-drop support.

    • Settings > System > Motherboard: Disable Floppy boot.

    • Settings > Audio: Disable audio.

    • Settings > USB: Disable USB (after setting pointing device to PS/2)

      pointing device

    • Settings > Display: Enable remote display.

    • Add a second Network adapter as a “Host-only Adapter”

INSTALL WINDOWS

  • Insert the iso in the storage section

    storage

  • You will be prompted to sign in to your Microsoft account, again skip this.

  • After the OS install is finished, install the VirtualBox Guest additions package on the VM (optional)

  • Create a local admin: vagrant /password: Vagrant (during or after installation)
net user vagrant vagrant /add /expires:never
net localgroup administrators vagrant /add
  • Make sure the network you are connected to is private. Run the below CMD
Set-NetConnectionProfile -NetworkCategory Private
PS C:\Windows\system32> Get-NetConnectionProfile 
Name             : Network 
InterfaceAlias   : Ethernet 
InterfaceIndex   : 6 
NetworkCategory  : Private <----- 
IPv4Connectivity : Internet 
IPv6Connectivity : NoTraffic

PREPARE WINDOWS FOR VAGRANT

Base Windows Configuration

  • Turn off UAC: run as admin in cmd prompt ( in one line)
reg add HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA /d 0 /t REG_DWORD /f /reg:64
  • Configure and Enable WinRM service: Run as admin each line &hit enter
winrm quickconfig -q winrm set 
winrm/config/winrs '@{MaxMemoryPerShellMB="512"}' 
winrm set winrm/config '@{MaxTimeoutms="1800000"}' 
winrm set winrm/config/service '@{AllowUnencrypted="true"}' 
winrm set winrm/config/service/auth '@{Basic="true"}' 
Set-Service WinRM -StartupType "Automatic" 
Start-Service WinRM
  • Note- WinRm is the alternative to SSH for windows boxes which allows Vagrant to connect to the box.
  • Relax the Powershell execution policy (run in PowerShell as admin)
Set-ExecutionPolicy Unrestricted -Force
  • Enable remote connection to your box
Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -name "fDenyTSConnections" -value 0 Enable-NetFirewallRule -DisplayGroup "Remote Desktop"
  • Disable complex passwords (Powershell)
secedit /export /cfg c:\secpol.cfg (gc C:\secpol.cfg).replace("PasswordComplexity = 1", "PasswordComplexity = 0") | Out-File C:\secpol.cfg secedit /configure /db c:\windows\security\local.sdb /cfg c:\secpol.cfg /areas SECURITYPOLICY rm -force c:\secpol.cfg -confirm:$false
  • Disable “Shutdown Tracker”
if ( -Not (Test-Path 'registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Reliability')) { New-Item -Path 'registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT' -Name Reliability -Force } Set-ItemProperty -Path 'registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Reliability' -Name ShutdownReasonOn -Value 0
  • Optional: Disable “Server Manager” starting at login (for server versions non-Core)
  • Optional: Clean unused files and zero free space on C drive (Optional)
C:\Windows\System32\cleanmgr.exe /d c:
  • Optional: Download and run sldete to zero out free space
PS C:\> sdelete.exe -z c:
  • Optional: allow PowerShell to display a progress bar when using the WinSSH communicator.
 if (!(Test-Path -Path $PROFILE)) { New-Item -ItemType File -Path $PROFILE -Force } Add-Content $PROFILE '$ProgressPreference = "SilentlyContinue"'

EXPORTING YOUR BASE BOX

  • Create a new Vagrantfile with some default settings that will allow your users and Vagrant to connect to the box
# -*- mode: ruby -*- 
# vi: set ft=ruby : 
# All Vagrant configuration is done below. The "2" in Vagrant.configure 
# configures the configuration version (for backwards compatibility). 
Vagrant.configure(2) do |config| 
config.vm.guest = :windows 
config.vm.communicator = "winrm" 
config.vm.boot_timeout = 600 
config.vm.graceful_halt_timeout = 600 
# Create a forwarded port mapping which allows access to a specific port 
# within the machine from a port on the host machine. 
config.vm.network "forwarded_port", guest: 80, host: 8080 
config.vm.network :forwarded_port, guest: 3389, host: 3389 
config.vm.network :forwarded_port, guest: 5985, host: 5985, id: "winrm", auto_correct: true 
config.vm.provider "virtualbox" do |vb| 
# Customize the name of VM in VirtualBox manager UI: 
  vb.name = "win10_pro_vm" 
  end 
end
  • Export the VirtualBox as a Vagrant box ( make sure your CDV drive is empty)
vagrant package --base Win10Pro --output /path/to/output/Win10Pro.box --vagrantfile /path/to/initial/Vagrantfile
  • Add the box to the vagrant repo you name it as you wish
vagrant box add /path/to/output/Win10Pro.box --name brokedba/Win10pro
  • Add winrm-fs and vbguest in your physical host to allow shared folders syncing and auto-install of Vbox Guest additions package (if not done on the base box)
vagrant plugin install winrm-fs vagrant plugin install vagrant-vbguest

Test the Vagrant Box

Yay!! you now have the box registered locally and ready to bounce

C:\> vagrant init 
C:\> vagrant up 
C:\> vagrant destroy --- to destroy the vm

Test this Vagrant Box online

If you want to spin this vagrant box without the hassle of creating the Vagrant box, you can try mine already as it’s already stored in Vagrant Cloud

You only need to:

win10pro

  1. Download a small VagrantFile (by clicking save as) and copy it to your local directory 
  2. Run the vagrant up command within the same directory 
C:\> vagrant up 
C:\> vagrant destroy --- to destroy the vm

Conclusion

– We have just demonstrated how to create a Vagrant box for Windows 10 that can be licensed later if needed.

– If you are on a Linux or Mac machine and are interested in installing Windows 11, there is a neat article about a shell script that will automatically install the OS for you through a new VirtualBox feature called:
              “Unattended install” >> Unattended-install-Microsoft-windows-11-on-VirtualBox