Building an Active Directory demo lab using Workflow to automatize the process


I’m trying to join two articles from the “Hey, Scripting Guy!” website:

    * Building a demo Active Directory ( * PowerShell Workflows: Restarting the Computer (

In other words, I’m trying to make one script file only to:

    * Rename server and restart * Name network connection, change IP address, install AD components, change administrator password, create domain and restart * Create base OU, other OUs and random users

I’ve tried using only one file but, it isn’t working…
So I have to split it on 3 files.

Here are the codes:

FILE “Configura_Lab.ps1”

WorkFlow Configura_Lab {

Restart-Computer -Force -Wait

(InlineScript {C:\Configurar\Passo1.ps1})


$actionscript = '-NonInteractive -WindowStyle Normal -NoLogo -NoProfile -NoExit -Command "&''C:\Configurar\Workflow.ps1''"'
$pstart =  "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
Get-ScheduledTask -TaskName Continuar_Workflow -ErrorAction SilentlyContinue | Unregister-ScheduledTask -Confirm:$false
$act = New-ScheduledTaskAction -Execute $pstart -Argument $actionscript
$trig = New-ScheduledTaskTrigger -AtLogOn
Register-ScheduledTask -TaskName Continuar_Workflow -Action $act -Trigger $trig -RunLevel Highest | Out-Null

#Renomear o servidor
$ServerName = Read-Host "Digite um nome para o servidor"
Rename-Computer $ServerName -Force -Passthru


FILE “Passo1.ps1”

WorkFlow Passo_2 {

(InlineScript {
$Empresa="Inventada LTDA",

#Configurar IP fixo
$NetAdaptersConnected = Get-NetAdapter | Where {$_.Status -eq "Up"}
If ($NetAdaptersConnected.count){
Write-Host "Adaptadores conectados encontrados:"
$NetAdapterSelected = Read-Host "Digite o número da interface (ifIndex) que deseja utilizar"
$NetAdapterSelected = $NetAdaptersConnected.ifIndex
Rename-NetAdapter -Name (Get-NetAdapter -ifIndex $NetAdapterSelected).name $Empresa
If ($Gateway){
New-NetIPAddress -AddressFamily IPv4 -IPAddress $IPAddress -PrefixLength $NetworkMask -DefaultGateway $Gateway -InterfaceIndex $NetAdapterSelected
New-NetIPAddress -AddressFamily IPv4 -IPAddress $IPAddress -PrefixLength $NetworkMask -InterfaceIndex $NetAdapterSelected
Set-DnsClientServerAddress -ServerAddresses $IPAddress -InterfaceIndex $NetAdapterSelected -PassThru

#Instalar Domain Services no servidor
INSTALL-WindowsFeature AD-Domain-Services –IncludeManagementTools -IncludeAllSubFeature

#Alterar senha de administrador local
Net user Administrator $Password

Restart-Computer -Force -Wait

(InlineScript {C:\Configurar\Passo2.ps1})


Get-Job -command Configura_Lab | Stop-Job
Get-Job -command Configura_Lab | Remove-Job


FILE “Passo2.ps1”

WorkFlow Passo_3 {

(InlineScript {


#Configurar o AD
Import-module ADDSDeployment

Install-ADDSForest –SkipPreChecks –CreateDnsDelegation:$False –DatabasePath ‘C:\Windows\NTDS’ –DomainMode ‘Win2012R2’ –DomainName $DomainName –DomainNetbiosname $DomainNETBIOSName –ForestMode ‘Win2012R2’ –InstallDns:$True –Logpath ‘C:\Windows\NTDS’ –NoRebootOnCompletion:$True –SysvolPath ‘C:\Windows\SYSVOL’ –SafeModeAdministratorPassword (CONVERTTO-SecureString $Password –asplaintext –force) –force:$true

Restart-Computer -Force -Wait

(InlineScript {C:\Configurar\Passo3.ps1})


Get-Job -command Passo_2 | Stop-Job
Get-Job -command Passo_2 | Remove-Job


FILE “Passo3.ps1”

Import-module ActiveDirectory

$ErrorActionPreference = "SilentlyContinue"

# Crude Random Password Generator 
Function GeneratePassword

# How many Characters Minimum?

# Create a password choosing everying from Character 34 to 127
1..$Length | foreach{ $Password+=([char]((Get-Random 93)+34))}

# Convert to a Secure String
$Password=Convertto-SecureString $Password -asplaintext -force
Return $Password

Function Get-GroupInfo()

$GroupName=$City.replace(" ","")+"-"+$Division.replace(" ","")
$GroupDescription="$Division in $City Access Group"

# Return the Results (This is a feature new to version 3)

$CityOU=“Tokyo”,”Redmond”,”Ottawa”,”Madrid”,”New Orleans”,”Queensland”

# Create BaseOU for Offices
NEW-ADOrganizationalUnit -name $BaseOU -path $Domain

# Gather through list of Cities
Foreach ($City in $CityOU) 
    # Create OU for City
    NEW-ADOrganizationalUnit -path $CompanyPath -name $City

    # Gather through list of Divisions
    Foreach($Division in $DivisionOU)

 # Create Division within City
 NEW-ADOrganizationalUnit -path "OU=$City,$CompanyPath" -name $Division

 # Create Group within Division and Description
 $Groupdata=Get-Groupinfo –City $City –Division $Division
 NEW-ADGroup -name $GroupName -GroupScope Global -Description $GroupDescription -Path "OU=$Division,OU=$City,$CompanyPath"

# Pull together list of CSV raw data supplied from Generator
$Names=IMPORT-CSV C:\Configurar\Sample_names.csv

# Generate 150 Random Users from pulled Raw data
For ($x=0;$x -lt 150;$x++)

 # Pick a Random First and Last Name
 $Firstname=GET-Random $Names.Firstname
 $Lastname=GET-Random $Names.Lastname
 $Displayname=$Lastname+” “+$Firstname
 # Pick a Random City
 $City=GET-RANDOM $Cityou

 # Pick a Random Division
 $Division=GET-RANDOM $DivisionOU

 # Define their path in Active Directory

 # Create the user in Active Directory
 New-ADUser -GivenName $Givenname -Surname $Surname -DisplayName $Displayname -UserPrincipalName $UserPN -Division $Division -City $City -Path $ADPath -name $Displayname -SamAccountName $Sam –AccountPassword (GENERATEPASSWORD)

 # Add User to appropriate Security Group
 $Groupname=(GET-GroupInfo –city $City –division $Division).Name
 ADD-ADGroupmember $Groupname –members $Sam

 # Enable the account for access
 ENABLE-ADAccount $Sam

Get-ScheduledTask -TaskName Continuar_Workflow | Unregister-ScheduledTask -Confirm:$false

ADDITIONAL FILE “SampleNames.txt”


ADDITIONAL FILE “Workflow.txt”

Import-Module PSWorkflow
Get-Job | Resume-Job

Why using that kind of approach it just don’t work using one file?
Whats happened: Using one file the computer was renamed, restarted, configured IP address, restarted and didn’t installed Active Directory. Just gave me errors saying that it can’t create those OU or users because there was no domain.

Any ideas?

That was a great article, but these days I’d use Desired State Configuration instead. Much easier to write and maintain. Is that an option?

Well, I’m kinda new to PowerShell… Will give a look at DSC and I’ll post here my opinion.

Thanks a lot!

I’d second DSC - the downloads will give you AD building capability has an ebook on the subject - I’m using it to build my own lab environment, and I posted my scripts in a blog post here last week, I think. They’d probably be decent examples for you to start with. MUCH more straightforward. Good luck.

I’m going to do it right now! Thank you both for the replies.