Cloud Knowledge

Your Go-To Hub for Cloud Solutions & Insights

Advertisement

Build a Windows Server 2025 Active Directory Lab in VirtualBox — End-to-End Guide (with Hybrid Entra ID)

Build a Windows Server 2025 Active Directory Lab in VirtualBox — End-to-End Guide (with Hybrid Entra ID)
Build a Windows Server 2025 Active Directory Lab in VirtualBox (Step-by-Step, with Hybrid Entra ID & Troubleshooting)
Hands-On Lab Windows Server 2025

Build a Windows Server 2025 Active Directory Lab in VirtualBox — End-to-End Guide (with Hybrid Entra ID)

In this extensive tutorial, you’ll set up a modern, reproducible Active Directory lab using Oracle VirtualBox, configure DNS, create a domain controller, join Windows 10/11 clients, and explore hybrid integration with Microsoft Entra ID. You’ll also get practical PowerShell and Microsoft Graph troubleshooting playbooks you can paste into your environment.

Time: ~2–3 hours
Difficulty: Intermediate
You’ll learn: AD, DNS, GPO, Hybrid, Troubleshooting
Host (Laptop/Desktop) VirtualBox VM: Windows Server 2025 Role: AD DS + DNS VM: Windows 10/11 Domain-Joined Client Internal Network (Host-Only / IntNet) DHCP optional • DNS via DC • No Internet leak Cloud: Microsoft Entra ID Hybrid (optional)

High-level view of the VirtualBox lab: internal network, domain controller, client, and optional Entra ID.

What you’ll build. A clean Active Directory domain with DNS on Windows Server 2025, one or more Windows 10/11 clients, a private internal network, and optional hybrid with Microsoft Entra ID for modern identity experiments. No corporate resources required.

Why build a VirtualBox AD lab today?

Physical hardware is costly and inflexible. VirtualBox on a laptop lets you quickly spin up a safe playground for Group Policy, joins, Kerberos, and hybrid identity. This lab is repeatable, snapshot-friendly, and perfect for certifications and interviews.

Prerequisites

  • A host with ≥ 16 GB RAM, 4+ cores, 60+ GB free SSD
  • Oracle VirtualBox installed (latest)
  • ISOs for Windows Server 2025 and Windows 10/11
  • Basic Windows admin familiarity

Tip: snapshots save hours—take one after each milestone.

Designing the lab topology

We’ll use two NICs on the domain controller: Adapter 1 = NAT (for Internet updates) and Adapter 2 = Internal Network (IntNet) providing services to clients. Clients use only Internal Network and point DNS at the DC.

ComponentRoleNotes
DC01AD DS, DNS2 vCPUs, 4–6 GB RAM, 60 GB disk
WIN10-01Client2 vCPUs, 4 GB RAM, 40 GB disk
IntNetInternal networkNo default gateway; DNS = DC01

Create the VMs and network

1
Define IntNet. In each VM’s Network settings, add Adapter 2 → Internal Network and give it a memorable name (e.g., CAC-Internal).
2
Attach ISOs. Mount the Windows Server ISO to DC01 and the Windows 10/11 ISO to the client.
3
Guest Additions. After installing each OS, insert VirtualBox Guest Additions for seamless mouse, display, shared folders, and time sync.

Install Windows Server 2025 and promote to a domain controller

During OS setup, choose Desktop Experience, set a strong Administrator password, and apply updates. Then configure static IP on the Internal NIC (e.g., 10.10.10.10/24), leave gateway empty, and set DNS to itself (10.10.10.10).

PowerShell: Core DC configuration

# Set static IP on internal NIC (rename if needed)
$nic = Get-NetAdapter | Where-Object { $_.Status -eq 'Up' -and $_.Name -like '*Ethernet*' } | Select-Object -First 1
New-NetIPAddress -InterfaceAlias $nic.Name -IPAddress 10.10.10.10 -PrefixLength 24
Set-DnsClientServerAddress -InterfaceAlias $nic.Name -ServerAddresses 10.10.10.10

# Install AD DS & DNS, then promote
Install-WindowsFeature AD-Domain-Services,DNS -IncludeManagementTools
Import-Module ADDSDeployment
Install-ADDSForest `
 -DomainName "lab.contoso.local" `
 -DomainNetbiosName "LAB" `
 -SafeModeAdministratorPassword (Read-Host "DSRM Password" -AsSecureString) `
 -InstallDNS:$true -Force

Reboot completes promotion. Take a snapshot named “DC-Promoted”.

Install Windows 10/11 and join the domain

  1. On the client, set the Internal NIC to 10.10.10.20/24, DNS = 10.10.10.10.
  2. Test name resolution: nslookup dc01.lab.contoso.local.
  3. Join: System > Rename this PC (advanced) > Change > Domainlab.contoso.local. Reboot.
Smoke test: From client, run nltest /dsgetdc:lab.contoso.local and gpupdate /force. You should see a healthy DC and policy refresh.

Essential DNS and AD checks (quick wins)

  • Forward lookup zone lab.contoso.local exists with _msdcs sub-zone.
  • Reverse zone optional but recommended (PTR records help troubleshooting).
  • dcdiag /v shows all PASS, repadmin /replsummary is clean (single-DC will be simple).

Creating baseline users, groups, and GPO

PowerShell: Create users & baseline GPO

# Create OU structure
New-ADOrganizationalUnit -Name "Corp" -Path "DC=lab,DC=contoso,DC=local"
New-ADOrganizationalUnit -Name "Users" -Path "OU=Corp,DC=lab,DC=contoso,DC=local"
New-ADOrganizationalUnit -Name "Workstations" -Path "OU=Corp,DC=lab,DC=contoso,DC=local"

# Add a test user
New-ADUser -Name "Ava Admin" -SamAccountName ava.admin -UserPrincipalName "ava.admin@lab.contoso.local" `
 -AccountPassword (ConvertTo-SecureString "P@ssw0rd123!" -AsPlainText -Force) -Enabled $true `
 -Path "OU=Users,OU=Corp,DC=lab,DC=contoso,DC=local"

# Baseline security GPO
New-GPO -Name "Baseline-Workstations" | New-GPLink -Target "OU=Workstations,OU=Corp,DC=lab,DC=contoso,DC=local"

# Example: Turn on Windows Defender Cloud-delivered protection
Set-GPRegistryValue -Name "Baseline-Workstations" `
 -Key "HKLM\SOFTWARE\Policies\Microsoft\Windows Defender\MpEngine" `
 -ValueName "MpCloudBlockLevel" -Type DWord -Value 2

Optional: Make it hybrid with Microsoft Entra ID

If you want single sign-on to SaaS and conditional access testing, add Microsoft Entra ID connect-style synchronization (using Microsoft Entra Connect or Cloud Sync). In a lab, a single forest, single domain, and a scoped OU are enough.

Licensing reminder: Some Entra features (e.g., Conditional Access, Risk policies) require P1/P2. In a lab, trials are fine.

Troubleshooting playbooks (copy-paste friendly)

Real labs shine when things go wrong. Below are concise recipes for the most common issues.

Playbook 1 — Client can’t join domain

  • DNS: Client must query DC’s DNS. ipconfig /all should show only 10.10.10.10 on the Internal NIC.
  • Time: Skew > 5 minutes breaks Kerberos. Sync to DC: w32tm /resync /rediscover.
  • Firewall: Ensure File and Printer Sharing, Remote Admin, and RPC are allowed between client and DC.
# On client: quick DNS & time checks
Resolve-DnsName lab.contoso.local
Test-Connection dc01 -Count 2
w32tm /query /status
w32tm /resync /rediscover

Playbook 2 — AD DS health basics

dcdiag /v
repadmin /replsummary
Get-EventLog -LogName "Directory Service" -Newest 20 | Format-Table -Auto

Playbook 3 — DNS lookups fail intermittently

# Restart DNS service and clear cache on DC
Restart-Service DNS
Clear-DnsServerCache

# On client, flush & test
ipconfig /flushdns
nslookup dc01.lab.contoso.local

Playbook 4 — Group Policy not applying

gpupdate /force
gpresult /h c:\temp\gp.html
Get-GPO -All | Select DisplayName,Id,CreationTime
Get-GPResultantSetOfPolicy -ReportType Html -Path C:\temp\rsop.html

Playbook 5 — LDAP/Kerberos sanity

nltest /dsgetdc:lab.contoso.local
klist purge
klist get host/dc01.lab.contoso.local
Test-ComputerSecureChannel -Verbose

Hybrid troubleshooting with Microsoft Graph (Entra ID)

When you enable sync (Connect or Cloud Sync), sign-ins and sync status often raise questions. The Microsoft Graph PowerShell SDK lets you pull live diagnostics. Install once on any Internet-connected management host (can be your DC if NAT is enabled).

Graph: Install & sign in

Install-Module Microsoft.Graph -Scope CurrentUser
Import-Module Microsoft.Graph
Connect-MgGraph -Scopes "User.Read.All","AuditLog.Read.All","Directory.Read.All"
Select-MgProfile -Name beta   # for some audit endpoints; switch to v1.0 where available

Graph: Check directory sync status

# Useful when using Entra Connect / Cloud Sync
Get-MgDirectoryOnPremisesSynchronization | Format-List

Graph: Inspect recent sign-ins (filter by failure)

Get-MgAuditLogSignIn -All `
 | Where-Object { $_.Status.ErrorCode -ne 0 } `
 | Select-Object CreatedDateTime,UserDisplayName,IpAddress,AppDisplayName,Status `
 | Sort-Object CreatedDateTime -Descending | Select-Object -First 25

Graph: List risky users & sign-ins (P2)

Get-MgRiskyUser -All | Select DisplayName, RiskLevel, RiskState
Get-MgIdentityProtectionRiskySignIn -All `
 | Select CreatedDateTime, UserDisplayName, RiskLevel, RiskDetail 

Graph: Export 30-day risky sign-ins to CSV

# Adjust days as needed
$since = (Get-Date).AddDays(-30)
Get-MgIdentityProtectionRiskySignIn -All `
 | Where-Object { $_.CreatedDateTime -ge $since } `
 | Select-Object CreatedDateTime,UserDisplayName,UserPrincipalName,IpAddress,Location,AppDisplayName,RiskLevel,RiskDetail `
 | Export-Csv -Path "$env:USERPROFILE\Desktop\risky-signins-30days.csv" -NoTypeInformation

Security hardening basics for the lab

  • Create separate admin and user identities; avoid day-to-day browsing on domain admin.
  • Enable Windows Firewall and limit RDP to the internal network.
  • Use Local Administrator Password Solution (LAPS) for local admin rotation.
  • Use GPO to disable SMB1, enforce NTP, and deploy Defender baselines.

PowerShell: Quick hardening snippets

# Disable SMB1
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force

# NTP: DC as reliable time source
w32tm /config /manualpeerlist:"time.windows.com,0x9" /syncfromflags:manual /reliable:yes /update
w32tm /resync /force

Lab “Day 2” exercises

  • Deploy a file server and test NTFS vs. share permissions.
  • Create and link a GPO for Windows Update rings on clients.
  • Add a second DC and test repadmin failover.
  • Enable Azure AD Connect staging mode, then cut over.

Common error messages decoded

ErrorRoot causeFix
“The specified domain either does not exist or could not be contacted.” DNS not pointing to DC; time skew Set DNS to DC IP only; w32tm /resync
“KDC_ERR_S_PRINCIPAL_UNKNOWN” SPN missing/mismatched Check with setspn -Q */hostname; fix SPN
Group Policy “Access is denied” SYSVOL/NETLOGON share or perms Verify shares, DFSR health; permissions on GPO

Inline “royalty-free” visuals for documentation

The SVG above and the following diagram are embedded shapes you’re free to reuse inside your WordPress post.

DC01 — AD DS + DNS WIN10-01 — Client Entra ID (Optional)
Simple, inline SVG cards representing the DC, client, and Entra ID.

Backup & snapshot strategy

Adopt a naming convention: “00-CleanOS”, “10-DC-Promoted”, “20-Client-Joined”. Snapshot just before risky changes (schema updates, GPO templates, Connect configuration) to save yourself from rebuilds.

Performance tuning tips for tiny hosts

  • Use fixed-size VDI or VHD where possible; it performs better than thin on heavy I/O.
  • Allocate only the RAM you need—swap hurts more than conservative sizing helps.
  • Keep ISO and VM disks on SSD; move backups to HDD/external.

Frequently asked “why” answers

Why an internal network? Isolation. It keeps your lab from colliding with home/office DNS or DHCP, and it’s safer for experiments.

Why NAT on the DC? For Windows Update, downloads, and Graph module installs without exposing your lab externally.

Why not bridge the client? You can, but then you must carefully manage DNS and routes—less predictable on Wi-Fi.

Copy-ready scripts to accelerate lab rebuilds

Script: Build baseline OUs, groups, and join logic

# Run on DC01 after promotion
$root = "DC=lab,DC=contoso,DC=local"
$corp = New-ADOrganizationalUnit -Name "Corp" -Path $root -ProtectedFromAccidentalDeletion $false
$ous  = "Users","Admins","Workstations","Servers"
$ous | ForEach-Object { New-ADOrganizationalUnit -Name $_ -Path $corp.DistinguishedName }

# Security groups
New-ADGroup -Name "Helpdesk Operators" -GroupScope Global -Path "OU=Admins,OU=Corp,$root"
New-ADGroup -Name "Workstation Users" -GroupScope Global -Path "OU=Users,OU=Corp,$root"

Entra ID Conditional Access & sign-in insights in the lab

With hybrid users available in Entra, you can test Conditional Access basics: block legacy auth, require MFA for privileged roles, or enforce compliant device for admin portals. Use Graph queries (above) to see effects in near real-time.

Checklist before you publish your lab notes

  • Document IPs, DNS zones, OU paths, GPO names.
  • Export GPOs and scripts to a repo (e.g., GitHub private).
  • Redact secrets from screenshots and commands.
You did it! You now have a portable, snapshot-driven Active Directory lab that can grow into federation, PKI, and modern identity experiments.

Appendix A — Quick reference commands

# DC health
dcdiag /v
repadmin /showrepl

# DNS
dnscmd /enumrecords lab.contoso.local @
Resolve-DnsName _ldap._tcp.dc._msdcs.lab.contoso.local

# Client
ipconfig /all
nltest /sc_verify:lab
Test-ComputerSecureChannel -Verbose
Remember: if name resolution fails, AD fails. Always confirm DNS → SRV → Kerberos before chasing ghosts.

Appendix B — Minimal Entra Connect notes

  • Use a cloud-only global admin for setup; do not reuse the on-prem Administrator.
  • Scope sync to OU=Users,OU=Corp,DC=lab,DC=contoso,DC=local while testing.
  • Consider Cloud Sync agent if you want lighter footprint.

Appendix C — Sample HTML callouts for WordPress blocks

AD DS

DNS

Group Policy

Entra ID

Microsoft Graph

Leave a Reply

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