Having a lab handy is a tremendous help when learning Windows administration. This post goes through an easy way to setup your own lab with Vagrant and Packer.

Update: I used this lab quite a bit since this post and did quite a bit of improvements. Most things remain correct but you will, for instance, have to replace eval-win2012r2-standard-ssh-nocm-1.0.4 with eval-win2012r2-standard-nocm-1.0.4 in the following examples for the lab to work. Please, refer to the github repository for details.

Even if, nowadays, it is fairly easy to setup a Windows Lab on various cloud providers, doing it by oneself is the best way to learn. However, it can quickly get time consuming. This post describes how Vagrant sets up automatically a new lab on my laptop each time I need to try something on a windows infrastructure.


Packer by Hashicorp is a tool for automated creation of machines and container images. It can do so for various target platforms. In the following lines we are going to create Windows machines targeted at VirtualBox.

The aforementioned site extensively documents how Packer works. However, automatic creation of a Windows machine is not an easy task. For those interrested the following post will walk you through the process of creating a Windows base image.

Because creating the base images is not the subject of this post we will take a shortcut and use packer definitions from the Boxcutter project which contains community-driven templates for most common OSes. After installing Packer (on the Mac, with brew, you can use brew install packer) execute the following commands:

git clone git@github.com:boxcutter/windows.git boxcutter-windows
cd boxcutter-windows
make virtualbox/eval-win2012r2-standard-ssh

This will take quite a bit of time: download the Windows evaluation ISO and then prepare, cleanup and package a VirtualBox base image.


After having installed Vagrant, go in the boxcutter directory mentioned above and execute:

vagrant box add --provider virtualbox \
       --name eval-win2012r2-standard-ssh-nocm-1.0.4 \
       -f box/virtualbox/eval-win2012r2-standard-ssh-nocm-1.0.4.box

Then in your Vagrantfile add the following definitions:

config.vm.define "dc" do |config|
  config.vm.box = "eval-win2012r2-standard-ssh-nocm-1.0.4"
  config.vm.network "private_network", ip: ""

config.vm.define "client" do |config|
  config.vm.box = "eval-win2012r2-standard-ssh-nocm-1.0.4"
  config.vm.network "private_network", ip: ""

The purpose of the private_network interface is to allow the boxes to both have fixed IP addresses (better for the DC) and to communicate directly with the host system. The NATed interfaces will allow the VMs to communicate with the rest of the world.

After executing:

vagrant up

and going for a lengthy coffee, you should have two VMs running called respectively dc and client.

The dc VM is provisionned as a domain controller. The provisioning part happens because of the following configuration in the Vagrantfile:

  config.vm.define "dc" do |config|
    # ...
    config.vm.provision "shell", path: "provision/00_admin_password.ps1"
    config.vm.provision "shell", path: "provision/01_install_AD.ps1"
    config.vm.provision "shell", path: "provision/02_install_forest.ps1"

A similar block is used for the client:

  config.vm.define "client" do |config|
    # ...
    config.vm.provision "shell", path: "provision/06_client_setup.ps1"

Setting up Active Directory

After setting up the VM with a blank Windows system we do the following:

  1. 00_admin_password.ps1: set the administrator password to Passw0rd.
  2. 01_install_AD.ps1 : install the various required features for Active Directory.
  3. 02_install_forest.ps1 : actually install the AD Forest.

On the client side the 06_client_setup.ps1 provisioning script will just setup DNS and join the client virtual machine to the newly created domain.

That is all we have for today, the actual Vagrant project can be found at https://github.com/dbroeglin/windows-lab