Jimm Wayans
Automated Lab

Automated Lab: Automate Your Active Directory Security Lab

Building an active directory security lab is not easy, it requires time and resources as well as skills. What if we had an automated way of doing all the hard work?

Well, that’s where AutomatedLab! Is convenient!

AutomatedLab (abbreviated as AL ) is an automated construction framework for Windows environments developed by Microsoft . You can use it to create labs in a variety of Active Directory environments. In addition to the local Hyper-V environment, it can also be built on Azure. And what I personally think is the most powerful is that by passing the lab construction script (ps1) to another person, he/she can build the same environment. I think this is ideal for training purposes and general learning.

Alright, let’s use AutomatedLab to automatically build the ideal Active Directory lab environment!

AutomatedLab (AL) enables you to

  • Set up lab and test environments
  • On Hyper-v or Azure with multiple products
  • Including just a single VM quickly.

Require one:

  • .NET 4.7.1 (Windows PowerShell)
  • .NET Core 2+ (PowerShell 6+)

Require one: Hyper-V Host Azure Subscription


  • Operating System DVD ISO Images


There are two options installing AutomatedLab:

  • You can use the MSI installer published on GitHub.
  • Or you install from the PowerShell Gallery using the cmdlet Install-Module.
    Please note that this is the ONLY way to install AutomatedLab and its dependencies in PowerShell Core/PowerShell 7 on both Windows and Linux/Azure Cloud Shell
Install-PackageProvider Nuget -Force
Install-Module AutomatedLab -AllowClobber

# If you are on Linux and are not starting pwsh with sudo
# This needs to executed only once per user - adjust according to your needs!
Set-PSFConfig -Module AutomatedLab -Name LabAppDataRoot -Value /home/youruser/.alConfig -PassThru | Register-PSFConfig

# Prepare sample content - modify to your needs

# Windows
New-LabSourcesFolder -Drive C

# Linux
Set-PSFConfig -Module AutomatedLab -Name LabSourcesLocation -Value /home/youruser/labsources -PassThru | Register-PSFConfig
New-LabSourcesFolder # Linux

From MSI

AutomatedLab (AL) is a bunch of PowerShell modules. To make the installation process easier, it is provided as an MSI.

Download Link: https://github.com/AutomatedLab/AutomatedLab/releases

There are not many choices when installing AL.


The options Typical and Complete are actually doing the same and install AL to the default locations. The PowerShell modules go to “C:\Program Files\WindowsPowerShell\Modules”, the rest to “C:\LabSources”.

As LabSources can grow quite big, you should go for a custom installation and put this component on a disk with enough free space to store the ISO files. This disk does not have to be an SSD. Do not change the location of the modules unless you really know what you are doing.


Very important to AL is the LabSources folder that should look like this:


If all that worked, you are ready to go.

Demo: See the power of AutomatedLab!

With AutomatedLab set up , try running the following PowerShell script with administrator privileges.

New-LabDefinition -Name Lab1 -DefaultVirtualizationEngine HyperV

Add-LabMachineDefinition -Name DC1 -Memory 1GB -OperatingSystem 'Windows Server 2019 Standard Evaluation (Desktop Experience)' -Roles RootDC -DomainName contoso.com
Add-LabMachineDefinition -Name Client1 -Memory 1GB -OperatingSystem 'Windows 10 Enterprise Evaluation' -DomainName contoso.com


Show-LabDeploymentSummary -Detailed

Doing this will create a Win 10 virtual machine on Hyper-V .

In just four lines, Windows Server and Windows10 are installed, Active Directory is built, and the client Windows10 is domain- joined.
How exciting!


Let’s set it up right away. Unfortunately, machine specs are required to run virtual machines . You will also need to download the Operating System ISO file, so it might take some time for those who start from scratch and it highly depends on your internet speed.


You need plenty of memory, storage, and processor. You need an environment where you can run multiple virtual machines at the same time.
At least 8GB of memory, depending on the virtual machines running at the same time. 16GB or 32GB is recommended depending on the number of virtual machines you are ging to create.

With storage as SSD, especially with NVMe SSD , the build time will be very fast.

Next step…

Keep the following enabled.
· BIOS on the screen Intel VT-X / AMD Enabling -V
· Windows Add in the deletion of features Hyper-V enabled related functions

VMWare for collisions with other virtualization software such as VMWare WorkStation is at 2004 Windows10 Hyper-V supports the platform.
If you want to use it in parallel, please update to Windows10 2004. Before 2004, you have no choice but to uninstall the virtualization software.
VirtualBox also seems to be compatible with the Hyper-V platform.


Install AutomatedLab
Start Powershell with administrator privileges and execute the following command.
Note: installation using msi may not be able to install all the necessary modules, so I do not recommend it.

Install-Module AutomatedLab -Force -AllowClobber

If you don’t have NuGet on your computer, you’ll be prompted to install NuGet, so follow the instructions to install it.

Installing LabSources Once
Once AutomatedLab is installed, install LabSources. LabSources are the folders where Labs are located.

> New-LabSourcesFolder

* If you want to install on another drive, specify with -DriveLetter.
(e.g “-Drive Letter D” etc.)

Getting an error  when executing an Automated Lab command

When you try to execute the Automated Lab command including this command, the following error may occur.

The’New-LabSourcesFolder’command was found in module’AutomatedLab’, but this module could not be loaded.

This is due to Powershell ‘s security enforcement policy, and there are two ways to resolve it.
1.  Permanently relax the execution policy
2.  Temporarily relax the execution policy by specifying the “-Exec bypass” option every time the Powershell window is executed.  * In this case, it is necessary to execute “Import-Module Automated Lab” every time when using AL.

The execution policy can be changed temporarily at the time of execution as shown in option 2, but when creating a lab configuration with Powershell ISE in the future , if you chose option 2, it will be blocked by the execution policy and execution will not be possible, so choose option 1.

Set-ExecutionPolicy Unrestricted

* Execute with administrator privileges

If you are concerned about security, return to the Restricted policy when you no longer use AL.

Whether to send diagnostic information when AutomatedLab is executed for the first time.

When you execute it for the first time, you will be asked the following questions.

Opt in to telemetry?

Whether to send diagnostic information. Please choose either Yes or No.

Download ISO file

AL is available if your ISO image contains a configuration file named install.wim. ISO files such as Windows 10 Pro downloaded using the
Windows Media Creation Tool do not contain wim files and cannot be used as is. The trial version of the ISO file includes install.wim, which you should use for verification purposes.

The trial version ISO file for each OS is as follows.

Windows Server 2019
Windows 10 Enterprise

Please prepare the English version (US) for all of these . The architecture is free, but this time we will use x64.
* You need to enter your name, company name, and phone number to download the ISO file.

After downloading the ISO file, place it in the ISOs folder inside the AL LabSources folder.
The LabSources folder is created directly under the C drive by default.

After deployment, use the Get-LabAvailableOperatingSystem command in Powershell to make sure the ISO file is recognized.

PS C:\WINDOWS\system32> Get-LabAvailableOperatingSystem |ft OperatingSystemImageName
20:30:25|00:48:57|00:48:57.052| Scanning 2 files for operating systems
Found 5 OS images.
Windows 10 Enterprise Evaluation
Windows Server 2019 Standard Evaluation
Windows Server 2019 Standard Evaluation (Desktop Experience)
Windows Server 2019 Datacenter Evaluation
Windows Server 2019 Datacenter Evaluation (Desktop Experience)

This completes the basic setup.

Let’s create our lab

Time required: 10-20 minutes (depending on machine specifications)

Since Sample Scripts exist in LabSources, you can understand the general method by looking at them.
Tutorials  on Github Wiki can help you.

In addition, the extensive documentation can be found at the following URL. However, it seems that it is not the latest, so be careful.
(For the latest information, you can only use Get-Help or read the code in the repository )

Let’s install Windows Server 2019.
First , run Windows Powershell  with administrator privileges.
Next, copy and paste the following commands to a text editor and save it as ps1 file.

# Declaration to create a lab called TestLab # Everything you 
set from now on is applied by executing the "Install-Lab" command 
# Default Virtualization Engine is Hyper-V. This is a required option. 
New-LabDefinition -Name TestLab -DefaultVirtualizationEngine HyperV

## Create a machine for Windows Server 2019 
# Powershell can split long command columns into multiple lines by putting a backticks (`) at the end. 
# -OperatingSystem: 
Add-LabMachineDefinition using the name of OperatingSystemImageName that appears in OperatingSystem `
 -Name ws2019 `
 -Memory 2GB `
 -OperatingSystem 'Windows Server 2019 Standard Evaluation (Desktop Experience)'

#Apply and create lab settings 

#Show deployment results 
Show-LabDeploymentSummary -Detailed

The edition is the same for both Standard and Datacenter as long as it is a trial version. If you want to use it for commercial use, it is best to use the Datacenter option in case you purchase a license.

Execute the script .

Once executed, the lab will start building.

Since the base image is created for each OS, it will take some time for the first time. The second and subsequent times are much faster.

After a while, the process will complete and you will see the Show-LabDeploymentSummary results.

If the account name and password are not specified when defining the machine, the information defined by default will be used.
As shown in the Summary, the administrator account is set to “Administrator” and the password is set to “Somepass1” by default.
The network settings are similar, by default a network with a subnet of / 24 is created to avoid conflicting with the host’s network in the range
You are not connected to the internet with this setting, but you can connect to your machine and do a lot of things.

Connect to the lab machine

Type the following commands at the shell prompt at the bottom of PowerShell ISE. You may want to keep the command window closed, as the command window on the right side of the screen may steal keyboard input.

RDP connection

You can use the Connect-LabVM command to make an RDP connection.

> Connect-LabVM ws2019

Enter “Administrator” as the user name and “Somepass 1″ as the password.

You can also use ” Remote Desktop Connection” (mstsc) directly. If you hit it on the command line :

> mstsc /v:ws2019
Establish a Powershell session with our lab machine

The lab machine has WinRM enabled by default, so PSSession is available.
By using Enter-LabPSSession, AL will use your credentials to establish the session.

> Enter-LabPSSession ws2019

[ws2019]: PS C:\Users\Administrator\Documents> whoami
Have your lab machine run Powershell cmdlets

Let’s make sure that Invoke -LabCommand can execute arbitrary code.

> Invoke-LabCommand -ComputerName ws2019 -ScriptBlock {Write-Host (whoami)}
19:21:19|00:03:09|00:00:00.000| Executing lab command activity: '<unnamed>' on machines 'ws2019'
19:21:19|00:03:09|00:00:00.009| - Waiting for completion
19:21:29|00:03:19|00:00:10.159| - Activity done

Invoke -LabCommand can specify a lab machine and use ScriptBlock to execute arbitrary PS code and OS commands. This time, the whoami command is output as standard output using the Write-Host cmdlet.
It’s not very useful at this point, but it’s sometimes used for post-processing after lab installation.

Create a domain environment

・Time required: 30-40 minutes

Next, based on “04 Single domain-joined server.ps1” in the Introduction folder of SampleScripts, create and build a script that installs Windows Server 2019 and sets the domain environment . This time we’ll set the domain administrator password with Add-Lab Domain Definition.

Paste the following script into PowerShell ISE and run it. Or you can paste it in a text editor and save it as filename.ps1 then run it on Powershell.
* It looks long, but most of them are comments (Tips).

# Delete if Lab already exists 
# Machine namespace is common to all labs, so be careful not to duplicate if you create while keeping the existing lab. 

# Declaration to create a lab called TestDomainLab 
#Everything you set from now on is applied by executing the "Install-Lab" command 
# Default Virtualization Engine is Hyper-V. This is a required option. 
New-LabDefinition -Name TestDomainLab -DefaultVirtualizationEngine HyperV

#Since DomainName is used on multiple machines, make it a variable. 
$TestDomain = 'al.corp' 

## Domain admin user information. 
$DomainAdminUser = "aladmin" 
$DomainAdminPassword = "ThisIsP@ssword123!"

## Set the user account at the time of OS installation for lab construction (local user). 
# Set-LabInstallationCredential is common within the lab. Overwriting is possible on the way. 
#For domain controllers, both Set-LabInstallationCredential and Add-LabDomainDefinition must match with the same information. 
# However, if you do so, you will have a "local administrator account" with the same information as the domain administrator account on a machine other than DC. 
#Therefore, when building a proper lab, kitting with the -InstallationUserCredential option of Add-LabMachineDefinition other than DC. #It is better to specify a local user separately. 
Set-LabInstallationCredential -Username $DomainAdminUser -Password $DomainAdminPassword

#Set domain administrator account 
Add-LabDomainDefinition -Name $TestDomain -AdminUser $DomainAdminUser -AdminPassword $DomainAdminPassword

## Create a domain controller 
# Powershell can split long command columns into multiple lines by putting a backticks (`) at the end. 
# -Roles: Specify a variable that indicates the role of the machine. Various settings are required for DC and SQL Server, but AL #predefines most of the settings in the form of Role. 
# Single or forest root domain controllers use the RootDC role. 
#See the About Roles section of the documentation for a list of # Roles. 
# -DomainName: Domain name. This time we tried to name it after Automated Lab. If you want to belong to the same domain, make each machine the same Domain Name. 
# This OS is not a desktop experience. This is recommended if you want to make the installation lighter.

Add-LabMachineDefinition `
-Name DC1 `
-Memory 2GB `
-OperatingSystem 'Windows Server 2019 Standard Evaluation' `
-Roles RootDC `
-DomainName $TestDomain

## the Windows10 machine is a client created (setup person who was in fact the client also WS2019 is fast) 
Add-LabMachineDefinition -Name Client1 -Memory 2GB -OperatingSystem 'Windows 10 Enterprise Evaluation' -DomainName $TestDomain

#Apply and create lab settings 

# Show deployment results 
Show-LabDeploymentSummary -Detailed

As you can see in the comments, the Install-Lab command starts the creation. You can change the configuration as much as you want.
If possible, it’s more time-efficient to fix the configuration over and over, then add Install-Lab at the end and run it, rather than repeating a time-consuming deployment each time. There are many things you can’t understand until you try it, so let’s make it with scrap and build before you get used to it.

As a result, it took about 30 minutes.

As I wrote in the comment of the script , due to the influence of Set-LabInstallationCredential, Client1 has a local administrator with the same information as the domain administrator account.
To avoid this, set up a local administrator account for kitting in the Add-LabMachineDefinition option.

The client also belongs to the al.corp domain .

Domain Admins also includes the “aladmin” configured in the build script .

[DC1]: PS C:\Users\aladmin\Documents> net group "Domain Admins" /domain
Group name     Domain Admins
Comment        Designated administrators of the domain


Administrator aladmin                  
The command completed successfully.

It took a while to set up the domain and set up Windows 10, but it ‘s very easy to set up two machines from scratch and wait just 30 minutes for the domain to be set up with a cup of coffee.
Let’s check using Enter-LabPSSession and Connect-LabVM Commands.

What are the settings such as user account? → Let’s do our best

Unfortunately, AL covers the automatic setup of the machine for the sake of brevity.
After building the machine, I will do my best to write PowerShell for additional setup such as user accounts, group additions, and group policies .
User accounts can be easily added using the New-ADUser cmdlet on the domain controller.

Post Installation Activity

AL has a “PostInstallationActivity” function that automatically executes a script in the virtual machine after building the virtual machine . PostInstallationActivity can be described in the definition options for each machine. Create a TestLab folder in C:\LabSources\PostInstallationActivities and save the following script as PrepareDomain.ps1 in the TestLab folder.

Start-Transcript C:\Windows\Temp\postinstall.log -append

$users = @()
$users += @{Name = "abe"; Password = "P@ssword1"}
$users += @{Name = "iijima"; Password = "P@ssword2"}
$users += @{Name = "usui"; Password = "P@ssword3"}

ForEach ($user in $users){
   $securePassword = $user.Password | ConvertTo-SecureString -AsPlainText -Force
   New-ADUser -Name $user.Name `
             -AccountPassword $securePassword `
             -PasswordNeverExpires $true `
             -Enabled $true 

Write-Output "Useradd done."


As you can see, this is a script that puts usernames and passwords in an array and adds them to New-ADUser in turn .

I am able to manage users, groups and OUs with csv for each domain.

By default, the password complexity requirement is enabled, so if you want to set a weak password, you need to change the group policy.

Next, add the PostInstallationActivity option to the domain controller in the build script above .

$postInstallActivity = Get-LabPostInstallationActivity `
                   -ScriptFileName PrepareDomain.ps1 `
                   -DependencyFolder "C:\LabSources\PostInstallationActivities\TestLab"

# Domain Contoller
Add-LabMachineDefinition `
-Name DC1 `
-Memory 1GB `
-OperatingSystem 'Windows Server 2019 Standard Evaluation' `
-Roles RootDC `
-DomainName $TestDomain `
-PostInstallationActivity $postInstallActivity

In the $postInstallActivity variable, declare the location of the folder of the script as an option of the Get-LabPostInstallationActivity cmdlet, and build the lab again.

After installation, you can confirm that the user is properly created as shown below.


Precautions after lab creation

In my build, I’ve identified the following security concerns in the default state: If you want to build a CTF-like environment and let others do it, please deal with these in advance.

– C:. \ Unattend Xml to include authentication information of kitting user
– AutoLogon is enabled by default, due to it included password in the HKLM\SECURITY\Policy\Secrets\DefaultPassword
– local administrator is enabled using in-kitting
-WinRM enabled
– UAC disabled
– Windows Firewall disabled

What do you think?

I would be more than happy to share the joy of building scripts for automating AD labs.
I enjoyed automation and wrote a lot of build scripts and PostInstallationActivity to create a vulnerable environment like the one below that could be set up in 2 hours fully; automatically.
Wayans corp

<script src=”https://gist.github.com/jimmwayans/daa86a8260aa74351206ef55769cb772.js”></script>

You can create two forests, connect MSSQL Database Links, Kerberoastable or ASReproastable, or RDP with Pth on a Restricted Admin machine, and you can create these complex environments with AutomatedLab (and lots of PowerShell ).
It was difficult but interesting to devise so that the NTLM hash always remains on a specific machine.

There are other ways to connect the virtual machine to the Internet, but it will be long, so I will omit it here. Check the SampleScripts folder for examples of their contents.
I enjoy validating the C2 framework by putting Squid on my router machine so that I can only reach the internet via a proxy.

Finally, I will end with a collection of frequently used AL commands.


Frequently used commands

All help can be found in Read the Docs below.
Here are some frequently used commands.

Whole lab

View list of labs

Get-Lab -List 

View a list of already installed labs.
The displayed lab can import sessions with the Import-Lab command.

Lab session restoration
Import-Lab [Lab name]

Restore installed lab sessions. Required to operate the lab again after closing the PowerShell window when it was built . Lab information is imported into a
Powershell session, allowing you to stop and start machines, get information, connect, and take snapshots.

List of lab machines

View lab machine information.

Obtaining detailed information during lab installation
Show-LabDeploymentSummary -Detailed

Display all machine names and network information, including the administrator user password at the time of installation.

Lab removal

Lab machines, network adapters, etc. are all deleted.

Stop and start the machine

Stop for a while
Save-LabVM [-Name <computer name> | -All]

The argument is the computer name, but using “-All” applies all lab machines.
State such as memory is saved. When it starts, it returns to its original state.

Stop-LabVM [-Name <computer name> | -All]

The argument is the computer name, but using “-All” applies all lab machines.
A shutdown signal is sent.

Start-LabVM [-Name <computer name> | -All]

The argument is the computer name, but using “-All” applies all lab machines.

snap shot

Take a snapshot
Checkpoint-LabVM [-ComputerName <computer name> | -All] -SnapshotName <snapshot name>

The argument is the computer name, but using “-All” applies all lab machines.

  • Specify the snapshot name with Snapshotname. Required.
> Checkpoint-LabVM -All -SnapshotName InitialSetup

* If the snapshot (Checkpoint) is not displayed in either Get-LabVM Snapshot or Hyper-V Manager even after executing this, it is possible that the creation has failed due to insufficient free space. Let’s try creating it with Hyper-V Manager and check the error content obtained.

Checking the snapshot
Get-LabVMSnapshot [-ComputerName <computer name>] 

If nothing is specified, information on all lab machines will be displayed.

> Get-LabVMSnapshot

SnapshotName CreationTime       ComputerName
------------ ------------       ------------
InitialSetup 2020/08/21 0:04:06 ws2016      
second       2020/08/21 0:05:55 ws2016
Restore snapshot
Restore-LabVMSnapshot [-ComputerName <computer name> | -All] -SnapshotName <snapshot name>

The argument is the computer name, but using “-All” applies all lab machines.

  • Specify the snapshot name with Snapshotname. Required.
> Restore-LabVMSnapshot -All -SnapshotName InitialSetup

Machine connection

Establish a Powershell session with a lab machine
Enter-LabPSSession -ComputerName <computer name>

A Powershell session is established with PSRemoting . If the lab machine belongs to a domain , the authentication information will be used by the domain admins user for kitting that was used when building the lab. If it does not belong to a
domain , the local kitting user’s credentials are used.

RDP connection to lab machine
Connect-LabVM -ComputerName <computer name>

You can also use the standard Windows Remote Desktop Client (mstsc).

mstsc /v: <computer name>


Establish a PSRemoting session with any credentials
$sess = New-LabPSSession -ComputerName <computer name> -Credential <PSCredential>

You can establish a PS session with any credentials. This works well if you change the domain administrator password after installing the lab .

The lab cannot detect that the password has been changed after installation and fails to log in.

Using the return value PSSession, you can open a PS session for the lab machine as follows.

Enter-PSSession -ComputerName <Computer Name> -Session <PSSession>
File transfer (host-> lab machine)
Copy-LabFileItem -ComputerName <Computer name> -Path <Host computer source file / directory> -DestinationFolderPath <Lab machine destination folder>

Transfer files from the host computer to the lab machine.
The identification information of the administrator user at the time of lab construction is used. All files / folders are placed with read-only attributes.

File Transfer 2 (Host-> Lab Machine)
Send-File -SourceFilePath <Source file on host computer> -DestinationFolderPath <Destination folder on lab machine> -Session <PSSession>

Send-Directory -SourceFolderPath <Host computer source directory> -DestinationFolderPath <Lab machine destination folder> -Session <PSSession>

Send the file to the lab machine using any PSSession information. Effective if you change the domain administrator password
after installing the lab .

File transfer (lab machine-> host)
Receive-File -SourceFilePath <Lab source file> -DestinationFolderPath <Host computer destination folder> -Session <PSSession>

Receive-Directory -SourceFolderPath <Lab source file> -DestinationFolderPath <Host computer destination folder> -Session <PSSession>

Receive files from lab machines using arbitrary PSSession information. Effective if you change the domain administrator password
after installing the lab .


I haven’t written enough yet, but I believe that if I write this far, some people will find it useful.
Let’s make your AD verification life easier with AutomatedLab!

My Powershell script for AL: @jimmwayans

Follow me on twitter for more infosec resources: @jimmwayans

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

× Need my services?