3 machine labs —1. Automating lab setup

Learning AD

deepak keshav
5 min readApr 22, 2022

This was an initiation called the Auror project by Sudarshan Pisupati that focusses on in-depth learning of AD. After the first session we were given a task for setting up automated AD lab setup incase if things go wrong and we have to setup the lab from the beginning ( which is a long process) .

Challenge

I researched on packer, vagrant, terraform, ansible to find suitable technology to create this lab setup. I went with packer to create golden image and vagrant to maintain the VM and to provision the VM with the config scripts

Pre-requisites:

  1. Install packer — https://www.packer.io/downloads
  2. Install Vagrant — https://www.vagrantup.com/downloads
  3. Install virtualbox — https://www.virtualbox.org/wiki/Downloads

While downloading packer, we get a zip file which needs to be extracted and the path of the extracted folder must be added to the path

setx path "%path%;<path_for_packer>"

The scripts used here is also available in my GitHub repository https://github.com/deepakkeshav98/Auror-project/tree/main/session%201

Packer:

This packer is going to create images for the virtualbox, so we need to install the virtualbox plugin for packer. Create a .pkr.hcl file and add the following code:

packer {
required_plugins {
virtualbox = {
version = ">= 0.0.1"
source = "github.com/hashicorp/virtualbox"
}
}
}

Now run command:

packer init

Since we are going to create the windows image in an automated manner so we have to create autounnatend.xml which will take care of the installation of OS completely with required configuration ( including username and password ). Packer requires winrm or SSH to connect with the image for further provisioning, we have to enable winrm in the windows machine. we have winrm.ps1 script to run after the initial logon of windows in the autounattend.xml file.

Running winrm.ps1 in the first logon commands ( autounattend.xml )

Since we are going to use vagrant to manage the VM, we have to create the output as a .box so that we can import using vagrant and run it. For this purpose we use post-processors to output the image in desired format ( vagrant for our need)

Post-processor for getting box

After having all the configurations JSON files ready for windows server 2016 and windows 10 packer, we can now build the image and save it as box for vagrant.

Run the following commands:

packer build /windows2016/win2016.json
packer build /windows10/win10.json

The box will be created in the respective folders.

The worst mistake I did was trying to add all the scripts to be provisioned in the packer itself ( each configuration change took 40–45 minutes since image has to be created and then provisioned ) , later I learnt that the efficient way was vagrant to provision these scripts :) .

Vagrant:

Initially we have to add the boxes to the vagrant and initialize the vagrant so that it creates Vagrantfile

vagrant box add win-16 <path_to_win2016box>
vagrant box add win-10 <path_to_win10box>
vagrant init

Since we are going to add multiple machine in a vagrant file , we have to configure both machine in vagrantfile

‘config.vm.define’ lets us to configure multiple VM in vagrantfile, using that we configure the required settings for each vm like ram size, cpu , static IP, subnet, scripts to be provisioned etc.

Create scripts to provision the following in windows server 2016 ( machine A):

  1. We are going to provision the windows server 2016 with AD and DNS server enabled using packer. so we provision the windows server 2016 image with powershell script with required domain name and basic configurations to enable Active directory.
$DomainAdmin      =  $env:username
$Password = "password@123"
$DomainPassword = ConvertTo-SecureString $Password -AsPlainText -Force
$DomainFQDN = "auror.local"
$DomainNetBios = $DomainFQDN.Split('.') | SELECT -First 1
$DomainSuffix = $DomainFQDN.Split('.') | SELECT -last 1
$admin = $DomainAdmin
$DomainUser = $admin + "@" + $domainFQDN
Write-Host "Starting isntall features"
Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools
Import-Module ADDSDeployment
Write-Host "Ad Deployment"
Install-ADDSForest `
-DomainName $DomainFQDN `
-DomainNetbiosName $DomainNetBios `
-DatabasePath "C:\NTDS" `
-LogPath "C:\NTDS" `
-SysvolPath "C:\SYSVOL" `
-DomainMode "WinThreshold" `
-ForestMode "WinThreshold" `
-CreateDNSDelegation:$false `
-InstallDns:$true `
-NoRebootOnCompletion:$true `
-Force:$true `
-SafeModeAdministratorPassword $DomainPassword
;

2. set Static IP to the server machine since it is going to act as DNS server (setdns.ps1)

Set-DnsClientServerAddress -InterfaceAlias "Ethernet 2" -ServerAddresses 127.0.0.1, 8.8.8.8

3. add user Adam with password Pass@123( adduser.ps1)

net user Adam Pass@123 /ADD /DOMAIN /Y

Create a script to provision few things in the windows 10 machine (machine B):

  1. Install chrome
  2. Join domain auror.local to windows server 2016
  3. make adam as the local admin ( use command net localgroup administrators adam /add)

4. Enable RDP connection

5. Reload the machine for all the changes to take place

Combining all into one script (initialise.ps1)

$Path = $env:TEMP; $Installer = 'chrome_installer.exe'; Invoke-WebRequest -Uri 'http://dl.google.com/chrome/install/375.126/chrome_installer.exe' -OutFile $Path\$Installer; Start-Process -FilePath $Path\$Installer -Args '/silent /install' -Verb RunAs -Wait; Remove-Item -Path $Path\$Installer
Set-DnsClientServerAddress -InterfaceAlias "Ethernet 2" -ServerAddresses 10.0.0.10
Set-NetFirewallProfile -Profile Domain, Public, Private -Enabled False
Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -name "UserAuthentication" -Value 0
Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server'-name "fDenyTSConnections" -Value 0
Enable-NetFirewallRule -DisplayGroup "Remote Desktop"
net localgroup Administrators adam /add
$Password = ConvertTo-SecureString -String 'vagrant' -AsPlainText -Force
# Create credential object
$Credential = New-Object System.Management.Automation.PSCredential ('Administrator', $Password)
$Settings = @{
DomainName = "auror.local"
DomainCredential = $Credential
}
Add-Computer @Settings

The reload plugin needs to be installed in order to restart the machine

vagrant plugin install vagrant-reload

After all the scripts are ready and provisioned to each machines, we can run the VM using

vagrant up

Conclusion:

This automation is using Packer and Vagrant, but don’t limit yourself only to this technique, there are other many solutions to automate the same, do explore and have fun

Even though it took me so much time and lot more patience (since I tried to provision everything in packer itself , later which I realized it is not the right way) , there was a very good learning on the automation part. I am very excited on the next sessions and upcoming challenge.

--

--