Setting up an Active Directory domain from scratch is one of the most valuable hands-on projects a Windows sysadmin can have in their portfolio. In this guide, you will build a fully functional simulated enterprise environment — complete with a Domain Controller, Group Policy, DNS, DHCP, and domain-joined workstation.
Skill level: Intermediate
What you need: 2 Windows VMs with at least 4 GB RAM each
Key Concepts
Before touching a single command, here is the mental model you need.
| Concept | What it is |
|---|---|
| Active Directory Domain Services (AD DS) | Microsoft's directory service. Stores information about every user, computer, and resource on a network, and controls who can access what. |
| Domain Controller (DC) | The server running AD DS. It authenticates logins, enforces policies, and is the authority for the entire domain. |
| Organisational Units (OUs) | Folders inside AD. You group users and computers into OUs so different policies can be applied to different departments cleanly. |
| Group Policy Objects (GPOs) | Rules linked to OUs that control security settings, drive mappings, restrictions, and more — applied automatically to every machine in scope. |
| DNS | AD DS relies entirely on DNS to locate the Domain Controller. Without correct DNS, domain joins fail and logins fail. |
| DHCP | Automatically assigns IP addresses and can push the correct DNS server address to every device on the network. |
How they fit together: AD DS is the database, the Domain Controller hosts it, OUs organise the records inside it, and GPOs are the rules attached to those records. DNS is the glue that lets every machine find the DC in the first place.
Lab Architecture
[Proxmox Host]
├── DC01 — Windows Server 2022 — 192.168.100.27 (Domain Controller)
└── WS01 — Windows 11 — 192.168.100.28 (Domain Member)
Gateway: 192.168.100.1
Domain: contoso.local
VM Specs
| VM | OS | Role | RAM | Disk | IP |
|---|---|---|---|---|---|
| DC01 | Windows Server 2022 (Desktop Experience) | Domain Controller | 4 GB | 60 GB |
192.168.100.27 (static) |
| WS01 | Windows 10 or 11 | Client workstation | 4 GB | 60 GB | 192.168.100.28 |
Phase 1 — Install & Configure DC01
Boot DC01 from the Windows Server 2022 ISO. Select Windows Server 2022 Standard (Desktop Experience) when prompted. Complete the installation and set a strong Administrator password.
Set a static IP address
A Domain Controller must always be reachable at the same IP. Dynamic addresses will break DNS and domain joins. Open PowerShell as Administrator:
# Set static IP
New-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress "192.168.100.27" `
-PrefixLength 24 -DefaultGateway "192.168.100.1"
### Rename the computer
Rename-Computer -NewName "DC01" -Restart
The VM reboots. Log back in as Administrator before continuing.
Phase 2 — Promote DC01 to Domain Controller
Install the AD DS and DNS roles
Install-WindowsFeature -Name AD-Domain-Services, DNS -IncludeManagementTools
⚠️ Common mistake:
Install-WindowsFeatureonly exists on Windows Server. If you see "term not recognised", you are running this on the wrong machine — confirm you are on DC01 running Server 2022, not your Windows 10/11 workstation.
Promote to Domain Controller
This command creates a new forest and domain called contoso.local. DC01 reboots automatically when complete.
Install-ADDSForest `
-DomainName "contoso.local" `
-DomainNetBiosName "CONTOSO" `
-SafeModeAdministratorPassword (ConvertTo-SecureString "P@ssw0rd123!" -AsPlainText -Force) `
-InstallDns `
-Force
After the reboot, log in as CONTOSO\Administrator. The login screen now shows the domain name — promotion was successful.
Connect via RDP from from your machine
First, go into the DC01 and enable remote desktop.

Next, if you are managing DC01 from a Linux machine using xfreerdp:
xfreerdp /v:192.168.100.27 /u:Administrator /d:CONTOSO /p:'YourPassword' /cert:ignore /dynamic-resolution /clipboard
Alternatively, you could connect using a GUI RDP client like Remmina (On Linux) or Remote Desktop. Remember that "domain" is CONTOSO
Phase 3 — Build the OU Structure
Organisational Units are the filing system of Active Directory. A well-designed OU structure makes GPO targeting clean and mirrors how real enterprises are organised.
contoso.local
└── Contoso Corp
├── IT
├── HR
├── Finance
├── Sales
├── Servers
├── Service Accounts
└── _Admin
$domain = "DC=contoso,DC=local"
# Top-level OU
New-ADOrganizationalUnit -Name "Contoso Corp" -Path $domain
$base = "OU=Contoso Corp,$domain"
# Department OUs
foreach ($ou in @("IT","HR","Finance","Sales","Servers","Service Accounts","_Admin")) {
New-ADOrganizationalUnit -Name $ou -Path $base
}
✅ The
_AdminOU uses an underscore prefix so it sorts to the top alphabetically — a common real-world convention for keeping privileged accounts visually separated from standard department OUs.
Phase 4 — Create Users & Groups
Rather than creating users manually through the GUI, use PowerShell (exactly how sysadmins handle bulk provisioning in production).
Create security groups
$groups = @("IT-Team","HR-Team","Finance-Team","Sales-Team")
foreach ($g in $groups) {
New-ADGroup -Name $g -GroupScope Global -GroupCategory Security `
-Path "OU=IT,OU=Contoso Corp,DC=contoso,DC=local"
}
Bulk-create users
$domain = "DC=contoso,DC=local"
$users = @(
@{First="Alice"; Last="Johnson"; Dept="IT"; OU="IT"},
@{First="Bob"; Last="Smith"; Dept="HR"; OU="HR"},
@{First="Carol"; Last="Davis"; Dept="Finance"; OU="Finance"},
@{First="Dan"; Last="Lee"; Dept="Sales"; OU="Sales"}
)
foreach ($u in $users) {
$username = ($u.First[0] + $u.Last).ToLower()
$upn = "$username@contoso.local"
$ouPath = "OU=$($u.OU),OU=Contoso Corp,$domain"
$password = ConvertTo-SecureString "Welcome1!" -AsPlainText -Force
New-ADUser `
-GivenName $u.First `
-Surname $u.Last `
-Name "$($u.First) $($u.Last)" `
-SamAccountName $username `
-UserPrincipalName $upn `
-Department $u.Dept `
-Path $ouPath `
-AccountPassword $password `
-Enabled $true `
-PasswordNeverExpires $false `
-ChangePasswordAtLogon $false
}
⚠️ RDP gotcha: Setting
-ChangePasswordAtLogon $trueblocks RDP logins entirely — the protocol cannot prompt for a password change mid-connection. Keep it$falsefor lab use. In production, set it to$trueso users choose their own password on first login.
Phase 5 — Configure Group Policy Objects (GPOs)
Group Policy Objects (GPOs) are rules you create and link to Organisational Units. Every user and computer inside that OU automatically receives and enforces those rules — no manual configuration needed on each machine. You manage GPOs through the Group Policy Management Console (GPMC), which was installed alongside AD DS earlier.
Open GPMC from DC01 via: Server Manager → Tools → Group Policy Management
GPO 1 — Security Baseline (linked to Contoso Corp)
This GPO applies to every user and computer under the Contoso Corp OU — think of it as your organisation-wide minimum security standard.
First, create and link the GPO via PowerShell:
New-GPO -Name "Security Baseline"
New-GPLink -Name "Security Baseline" -Target "OU=Contoso Corp,DC=contoso,DC=local"
Then configure the settings inside GPMC.
To find it, in the left panel, expand:
Forest: contoso.local → Domains → contoso.local → Group Policy Objects
You should see Security Baseline listed there.
Right-click Security Baseline → Edit to open the Group Policy Management Editor, then follow each path below:
- Enforce UAC (User Account Control) UAC is a Windows security feature that prevents unauthorised changes to the system by prompting for administrator approval. Enforcing it via GPO ensures users cannot disable it locally.
Computer Configuration → Policies → Windows Settings → Security Settings → Local Policies → Security Options
Set "User Account Control: Run all administrators in Admin Approval Mode" → Enabled
- Minimum Password Length
Enforces that no account in the domain can have a password shorter than 12 characters.
Computer Configuration → Policies → Windows Settings → Security Settings → Account Policies → Password Policy
Set "Minimum password length" → 12 characters
- Account Lockout Policy
Locks an account after repeated failed login attempts, protecting against brute-force attacks. After 15 minutes the account unlocks automatically.
Computer Configuration → Policies → Windows Settings → Security Settings → Account Policies → Account Lockout Policy
Set "Account lockout threshold" → 5 invalid logon attempts
Set "Account lockout duration" → 15 minutes
Set "Reset account lockout counter after" → 15 minutes
GPO 2 — Workstation Lockdown (linked to non-IT OUs)
This GPO restricts what standard users can do on their workstations. You will link it to HR, Finance, and Sales — but not IT, since your IT team needs unrestricted access to manage systems.
First, create and link the GPO to each non-IT department OU:
New-GPO -Name "Workstation Lockdown"
# Link to each non-IT OU
foreach ($ou in @("HR","Finance","Sales")) {
New-GPLink -Name "Workstation Lockdown" `
-Target "OU=$ou,OU=Contoso Corp,DC=contoso,DC=local"
}
Then in GPMC, right-click Workstation Lockdown → Edit
... then configure the following:
- Disable Access to Control Panel and PC Settings
Prevents standard users from changing system settings, uninstalling software, or modifying network configuration — common restrictions in managed enterprise environments.
User Configuration → Policies → Administrative Templates → Control Panel (Click on it)
Double-click "Prohibit access to Control Panel and PC Settings" → Set to Enabled → Click OK
- Prevent Access to Command Prompt
The Command Prompt (cmd.exe) can be used to bypass desktop restrictions. Disabling it for non-IT users reduces the risk of accidental or deliberate system changes.
User Configuration → Policies → Administrative Templates → System
Double-click "Prevent access to the command prompt" → Set to Enabled
When prompted "Disable the command prompt script processing also?" → Select No (selecting Yes would also break logon scripts, which you don't want)
Click OK
- Remove Run Dialog from Start Menu
The Run dialog (Win + R) gives users a quick way to launch programs and access network paths, which can be used to circumvent other restrictions. Removing it closes that gap.
User Configuration → Policies → Administrative Templates → Start Menu and Taskbar
Double-click "Remove Run menu from Start Menu" → Set to Enabled → Click OK
Verify the GPO is linked correctly
foreach ($ou in @("HR","Finance","Sales")) {
Write-Host "`n--- $ou ---"
Get-GPInheritance -Target "OU=$ou,OU=Contoso Corp,DC=contoso,DC=local" |
Select-Object -ExpandProperty GpoLinks
}
You should see Workstation Lockdown listed under each of the three OUs.
GPO 3 — IT Drive Mapping (linked to IT OU)
First create the share on DC01:
New-Item -Path "C:\Shares\ITShare" -ItemType Directory
New-SmbShare -Name "ITShare" -Path "C:\Shares\ITShare" `
-FullAccess "CONTOSO\IT-Team" -ReadAccess "CONTOSO\Domain Users"
Next, Create the Drive Map in GPMC manually...
This part is done entirely through the GUI. In GPMC, right-click Workstation Lockdown (or whichever GPO is linked to the IT OU) → Edit, then navigate to:
User Configuration → Preferences → Windows Settings → Drive Maps

Right-click in the right-hand pane → New → Mapped Drive
Then in GPMC: User Configuration → Preferences → Windows Settings → Drive Maps → map \\DC01\ITShare to Z: for the IT OU.
Phase 6 — Join WS01 to the Domain
On WS01, first point DNS at DC01. Without this, WS01 cannot resolve contoso.local and the domain join will fail.
Step 1: Open Network Settings → Change adapter options → IPv4 Properties. Set Preferred DNS to 192.168.100.27.
Step 2: Join the domain — run this on WS01 as Administrator:
Add-Computer -DomainName "contoso.local" `
-Credential (Get-Credential) `
-OUPath "OU=IT,OU=Contoso Corp,DC=contoso,DC=local" `
-Restart
Step 2.5: Allow ajohnson to use RDP
Domain users are not automatically allowed to RDP into machines — you need to add them to the local Remote Desktop Users group on WS01:
powershellAdd-LocalGroupMember -Group "Remote Desktop Users" -Member "CONTOSO\ajohnson"
Or to allow all domain users to RDP into WS01:
powershellAdd-LocalGroupMember -Group "Remote Desktop Users" -Member "CONTOSO\Domain Users"
Step 3: RDP into WS01 from Linux as a domain user:
xfreerdp /v:192.168.100.28 /u:ajohnson /d:CONTOSO /p:'Welcome1!' /cert:ignore /dynamic-resolution /clipboard
Step 4: Verify GPOs applied correctly:
# Quick summary in terminal
gpresult /r
# Full HTML report
gpresult /h "C:\Users\ajohnson\Documents\gp-report.html"
Bonus — DNS & DHCP
Verify and extend DNS
Do the the following in DC01...
# View all DNS zones
Get-DnsServerZone
# View A records in contoso.local
Get-DnsServerResourceRecord -ZoneName "contoso.local" -RRType A
# Add a custom record for a simulated intranet server
Add-DnsServerResourceRecordA -ZoneName "contoso.local" `
-Name "intranet" -IPv4Address "192.168.100.29"
Install and configure DHCP
Install-WindowsFeature DHCP -IncludeManagementTools
Add-DhcpServerv4Scope -Name "CorpLAN" `
-StartRange "192.168.100.100" -EndRange "192.168.100.199" `
-SubnetMask "255.255.255.0"
Set-DhcpServerv4OptionValue -ScopeId "192.168.100.0" `
-DnsServer "192.168.100.27" -Router "192.168.100.1"
Add-DhcpServerInDC -DnsName "dc01.contoso.local"
Skills This Project Demonstrates
- Active Directory DS — forest/domain deployment, OU structure design
- Group Policy — security baseline, account lockout, drive map preferences
- DNS & DHCP — zone management, custom records, scope configuration
- PowerShell automation — bulk user/group creation, role installation
- Windows networking — static IPs, domain join, name resolution
- Security fundamentals — password policy, account lockout, UAC enforcement
Wrapping Up
You now have a fully functional enterprise-grade Active Directory environment running in your lab — a Domain Controller, a domain-joined workstation, a structured OU hierarchy, enforced Group Policy, DNS, and DHCP, all provisioned largely through PowerShell.
Want to extend this? Here are possible next steps:
- Add a second domain controller and explore AD replication — understanding how DCs sync is essential knowledge for any enterprise environment
- Set up RSAT on WS01 and practice managing the domain entirely from the workstation, the way most administrators actually work day-to-day
- Simulate a user offboarding workflow — disable the account, move it to a dedicated Disabled OU, strip group memberships, and document the process as a runbook
-
Explore fine-grained password policies — apply stricter password requirements to the
_AdminOU without affecting standard users - Break something on purpose — delete a GPO link, misconfigure DNS, corrupt a user account — and practice diagnosing and recovering from it. Troubleshooting under pressure is a skill, and the only way to build it is to practise it in a safe environment
Found this useful? Drop a comment below or connect with me — I am always happy to talk through home lab setups and sysadmin career questions.
-> See the GitHub Repo
-> Connect with me On LinkedIn





Top comments (0)