How to Build the Perfect Hyper-V Test Environment

One task that seems to come up on a rather frequent basis is the request from project X to build them a test environment. They have a new application to deploy and they need to perform some testing. This is a prime candidate for automation. If your organization has adopted DevOps processes, then the ability to build and rebuild environments at the drop of a hat is a task that you’re expected to perform – except this time you’re doing it in production.
In this series of posts, I’m going to show you how you can use PowerShell scripts and PowerShell Direct to create the optimal hyper-v test environment. To begin, I will assume that you have a method to create VMs. Whether VM creation is performed from scratch, via templates or an automated build process isn’t relevant for these posts – whatever works in your organization is fine. The series will comprise 4 parts:

  • Part 1 – Creating an Active Directory [this post] – how to create a new AD forest and add a second Domain Controller to that forest (you do have 2 DCs in your environments don’t you?). I will assume you’re familiar with performing standard AD administrative tasks (if not, I recommend you read Learn Active Directory Management in a Month of Lunches)
  • Part 2 – populating your Active Directory with some OUs, accounts & groups. We’ll look at object creation singly and in bulk
  • Part 3 – how to add a member server then install and configure IIS. The second half of the post deals with adding a second member server and configuring it as a file server
  • Part 4 – installing a simple application then configure IIS to pull & display files from the file server. We’ll make people log in to the web server so that the accounts we created are used.

Hyper-v test environment

Building the Perfect Hyper-V Test Environment – Where to Start

I stated earlier that I’m using PowerShell Direct and PowerShell scripts to perform the configuration work. What about Desired State Configuration (DSC) you might ask. DSC is available from PowerShell v4 onwards – Windows Server 2012 R2 has it installed OOB and it’s available for some earlier versions of Windows Server as part of the Windows Management Framework (WMF) download. DSC needs a fair amount of explanation if you’ve not used it before so I’ll concentrate on scripting the configuration changes for now. I may get the opportunity to present this concept using DSC at a future date to give you the ability to compare and contrast the two approaches.
The starting point for this series is a brand new shiny VM that you’ve created, performed basic configuration (IP address etc) and patched. My previous posts Introduction to PowerShell Direct and How to Patch Hyper-V virtual machines through PowerShell Direct can help you get that job done.
Just to make the whole task more “interesting” I thought I’d only use Server Core machines so that all tasks have to be performed through code.

Create First Domain Controller

The first job to tackle is creating the first domain controller in our Active Directory (AD) and therefore creating the domain. I’m only going to create an AD forest with a single domain though these techniques can be easily adapted to create a multi-domain forest if you need one. Creating the first domain controller in a new domain requires you to:

  • Install the Active Directory Domain Services and DNS Windows roles
  • Promote the server to be a domain controller and create the domain

Install roles

Let’s start by installing the required roles. You’ll be running a number of commands against the VM so a remoting session is the most efficient way to connect:

$vm = 'TestDC01'
$cred = Get-Credential -Credential "$vmAdministrator"
$s = New-PSSession -VMName $vm -Credential $cred

What do you actually need to install?

$sb = {Get-WindowsFeature -Name AD*, DNS }
Invoke-Command -Session $s -ScriptBlock $sb | 
select DisplayName, Name, InstallState
DisplayName                                     Name                   InstallState
 -----------                                     ----                   ------------
 Active Directory Certificate Services           AD-Certificate         Available
 Certification Authority                         ADCS-Cert-Authority    Available
 Certificate Enrollment Policy Web Service       ADCS-Enroll-Web-Pol    Available
 Certificate Enrollment Web Service              ADCS-Enroll-Web-Svc    Available
 Certification Authority Web Enrollment          ADCS-Web-Enrollment    Available
 Network Device Enrollment Service               ADCS-Device-Enrollment Available
 Online Responder                                ADCS-Online-Cert       Available
 Active Directory Domain Services                AD-Domain-Services     Available
 Active Directory Federation Services            ADFS-Federation        Available
 Active Directory Lightweight Directory Services ADLDS                  Available
 Active Directory Rights Management Services     ADRMS                  Available
 Active Directory Rights Management Server       ADRMS-Server           Available
 Identity Federation Support                     ADRMS-Identity         Available
 DNS Server                                      DNS                    Available

I’ve cheated a little with this code as I have a good idea of the names of the features to install. We need to install AD-Domain-Services and DNS.
Run this code:

$sb = {Install-WindowsFeature -Name AD-Domain-Services, DNS -IncludeAllSubFeature -IncludeManagementTools -Restart}
Invoke-Command -Session $s -ScriptBlock $sb

You need to use the -IncludeAllSubFeatures to ensure that you get any additional sub-features the roles require. -IncludeManagementTools ensures you get the tools to manage the role installed on your server – in this case the PowerShell cmdlets to manage AD and DNS. The -Restart parameter will restart your VM after the installation has finished but only if required. As a side note, you may see code that uses Add-WindowsFeature instead of Install-WindowsFeature. Add-WindowsFeature was the cmdlet name when originally introduced with Windows Server 2008. It was later changed to Install-WindowsFeature but Add-WindowsFeature is still available as an alias so using that command will also work.
You should see results like this:

 PSComputerName : TestDC01
 RunspaceId     : e5c81a53-765f-4923-8dbd-a0e3d066b56d
 Success        : True
 RestartNeeded  : No
 FeatureResult  : {Active Directory Domain Services, DNS Server, Group Policy Management,
 Remote Server Administration Tools...}
 ExitCode       : Success

If you rerun the Get-WindowsFeature code from earlier you’ll see that the InstallState has changed to Installed.

Promote domain controller

Now that you’ve got the features installed how do you promote the server to be a domain controller and create the domain? In the past, you’d have to use DCPROMO but that option isn’t available anymore – now you must use the members of the ADDSDeployment module which is installed when you install the AD Domain Services role.

 PS C:Scripts> Get-Command -Module ADDSDeployment

CommandType     Name                                               Version    Source
 -----------     ----                                               -------    ------
 Cmdlet          Add-ADDSReadOnlyDomainControllerAccount      ADDSDeployment
 Cmdlet          Install-ADDSDomain                           ADDSDeployment
 Cmdlet          Install-ADDSDomainController                 ADDSDeployment
 Cmdlet          Install-ADDSForest                           ADDSDeployment
 Cmdlet          Test-ADDSDomainControllerInstallation        ADDSDeployment
 Cmdlet          Test-ADDSDomainControllerUninstallation      ADDSDeployment
 Cmdlet          Test-ADDSDomainInstallation                  ADDSDeployment
 Cmdlet          Test-ADDSForestInstallation                  ADDSDeployment
 Cmdlet          Test-ADDSReadOnlyDomainControllerAccountCreation    ADDSDeployment
 Cmdlet          Uninstall-ADDSDomainController               ADDSDeployment

The three important cmdlets, at this stage, are:

  • Install-ADDSForest – create new AD forest
  • Install-ADDSDomain – create new domain in existing forest
  • Install-ADDSDomainController – add a domain controller to an existing domain

You’ll use Install-ADDSForest to create the new forest:

$sb = {
Install-ADDSForest  -ForestMode 7 -DomainMode 7 `
-DomainName 'myorg.test'  -DomainNetbiosName 'myorg' `
-InstallDns:$true -CreateDnsDelegation:$false `
-DatabasePath 'C:WindowsNTDS' -LogPath 'C:WindowsNTDS' `
-SysvolPath 'C:WindowsSYSVOL' `
Invoke-Command -Session $s -ScriptBlock $sb

You’ll be prompted for the Safe Mode Administrator password – and again for its confirmation.
The parameters are reasonably self-explanatory. The database, log, and SYSVOL paths are the defaults but I like to include them to make sure I think about their placement. The -InstallDns parameter will configure DNS, creating the appropriate zones and records. A DNS delegation won’t be created.
The forest and domain modes need some explanation. A value of 7 means Windows Server 2016 forest and domain level. For legacy operating systems you could use Win2008, Win2008R2, Win2012 or Win2012R2 as appropriate. It seems that a value for Windows Server 2016 wasn’t added to the cmdlet! The values for forest mode and therefore the operating systems you can use as domain controllers in your forest are listed here. This link will also show the equivalent at the domain level.
As the script runs, you’ll see a warning about the script asking for passwords, possibly issues with network adapters if any are configured with DHCP, DNS delegations even though you told it not to create one and Windows Server 2016 security settings. If you run the code in the PowerShell ISE you’ll see progress messages.
When the script has finished you’ll see something like this:

 PSComputerName : TestDC01
 RunspaceId     : e5c81a53-765f-4923-8dbd-a0e3d066b56d
 Message        : Operation completed successfully
 Context        : DCPromo.General.1
 RebootRequired : False
 Status         : Success

Notice the RebootRequired returns false – even though you told it to reboot.
At this stage, you’ve got your first domain controller built and the AD forest is created. You now need a VM to use as the second DC.
Your remoting session will have been broken because the VM rebooted to finalize the domain controller creation. If you need to re-establish the session use the domainAdministrator form for the credential:

$cred = Get-Credential -Credential 'myorgAdministrator'
$s = New-PSSession -VMName TestDC01 -Credential $cred

Create Second Domain Controller

Creating the second domain controller is a similar process to creating the first except you use Install-ADDSDomainController. First create, configure and patch your VM.
Install AD Domain services and DNS:

$vm = 'TestDC02'
$cred = Get-Credential -Credential "$vmAdministrator"
$s = New-PSSession -VMName $vm -Credential $cred
$sb = {Install-WindowsFeature -Name AD-Domain-Services, DNS -IncludeAllSubFeature -IncludeManagementTools -Restart}
Invoke-Command -Session $s -ScriptBlock $sb

Then run this code:

$sb = {
$cred = Get-Credential 'myorgAdministrator'
Install-ADDSDomainController `
-Credential $cred `
-NoGlobalCatalog:$false `
-CreateDnsDelegation:$false `
-CriticalReplicationOnly:$false `
-DatabasePath 'C:WindowsNTDS' `
-DomainName 'myorg.test' `
-InstallDns:$true `
-LogPath 'C:WindowsNTDS' `
-NoRebootOnCompletion:$false `
-SysvolPath 'C:WindowsSYSVOL' `
Invoke-Command -Session $s -ScriptBlock $sb

You should get results like this returned:

 PSComputerName : TestDC02
 RunspaceId     : 9bdcd659-4c5c-4764-9050-1e1d07e0fa13
 Message        : Operation completed successfully
 Context        : DCPromo.General.1
 RebootRequired : False
 Status         : Success

By default, the new domain controller will be configured as a global catalog and won’t use critical replication. The parameters for these options in the code are for completeness so that you have an explicit statement of what has been performed. In a new AD, the domain controller will be added to the default site. If you want to add the domain controller to a specific site then you use the -SiteName parameter:

-SiteName ‘Site1’


You’re already well on your way to creating the perfect Hyper-V test environment! Now that you’ve got your domain controllers built it’s time to create some user accounts which we’ll get to in the next post in this series. In the meantime, why not ensure you have the perfect system set up for your test environment by implementing 6 Hardware Tweaks that will Skyrocket your Hyper-V Performance.


Altaro Hyper-V Backup
Share this post

Not a DOJO Member yet?

Join thousands of other IT pros and receive a weekly roundup email with the latest content & updates!

3 thoughts on "How to Build the Perfect Hyper-V Test Environment"

Leave a comment or ask a question

Your email address will not be published. Required fields are marked *

Your email address will not be published. Required fields are marked *

Notify me of follow-up replies via email

Yes, I would like to receive new blog posts by email

What is the color of grass?

Please note: If you’re not already a member on the Dojo Forums you will create a new account and receive an activation email.