Cloud Knowledge

Your Go-To Hub for Cloud Solutions & Insights

Advertisement

Build a Secure Windows Server 2025 Active Directory Virtual Lab in VirtualBox — Step-by-Step

Build a Secure Windows Server 2025 Active Directory
Build a Secure Windows Server 2025 Active Directory Virtual Lab in VirtualBox — Step-by-Step

Build a Secure Windows Server 2025 Active Directory Virtual Lab in VirtualBox — Step-by-Step

Complete hands-on lab guide • Windows Server 2025 • VirtualBox • AD DS • DHCP & DNS • PowerShell & Graph API

This tutorial walks you through building an isolated VirtualBox lab with Windows Server 2025 as a Domain Controller, joining Windows 10/11 clients, configuring DHCP/DNS, and performing advanced troubleshooting and automation using PowerShell and Microsoft Graph API.

Domain Controller Windows 10 Client Internet / NAT

Overview & Objectives

This guide helps IT pros, students, and cybersecurity learners build an isolated, production-like Active Directory environment using VirtualBox, Windows Server 2025, and Windows 10 clients. The lab teaches:

  • How to provision Windows Server 2025 and promote it to an Active Directory Domain Controller (AD DS).
  • Configure DHCP and DNS for automated address assignment and name resolution.
  • Join Windows 10 clients to the domain.
  • Perform advanced troubleshooting with PowerShell scripts for AD replication, DNS, and GPO issues.
  • Automate tasks (user creation, group assignment, device registration) using the Microsoft Graph API.
  • Apply best-practice security hardening to make the lab resilient and realistic.

Requirements & Downloads

Hardware: 16GB RAM recommended, 4+ CPU cores, 60GB+ free disk space. For a lightweight lab a machine with 8GB can run 2-3 VMs (but expect limited performance).

Software & resources:

  • Oracle VirtualBox (latest)
  • Windows Server 2025 ISO (evaluation or licensed)
  • Windows 10 / Windows 11 ISO for clients
  • Guest Additions for VirtualBox
  • PowerShell 7.x (optional but recommended)
  • Microsoft Graph PowerShell module (for automation examples later)
Tip: Save all ISO files in a dedicated "lab-media" folder. Use snapshots for restore points during major configuration milestones.

VirtualBox VM Setup (concise, adapted from your PDF)

Follow these condensed steps to create the VMs (detailed screenshots are in your uploaded PDF):

  1. Create a new VM in VirtualBox: select Windows type and the matching version, allocate 4GB+ RAM for the server (8GB preferred if you have it), 2+ CPUs, and create a dynamically allocated VDI disk (50GB+).
  2. Attach the Windows Server 2025 ISO to the VM's optical drive (Settings → Storage → Controller). Configure network adapters: Adapter 1 → NAT (for internet), Adapter 2 → Internal Network (e.g., "Lab-Internal").
  3. Install the OS, apply updates, set a static IP on the server (e.g., 192.168.50.2/24), and configure DNS to point to itself (127.0.0.1 or its static IP).
  4. Snapshot the VM after initial OS install and updates.
  5. Repeat for Windows 10 clients (smaller RAM/disk footprint). Join clients to the internal network and install VirtualBox Guest Additions on each.

Deploy Active Directory & Promote Domain Controller

On the prepared Windows Server 2025 VM:

  1. Install the AD DS role using Server Manager or PowerShell. Recommended: use PowerShell for repeatable automation.
# Install AD DS and DNS via PowerShell (run as Administrator)
Install-WindowsFeature -Name AD-Domain-Services, DNS -IncludeManagementTools

Import-Module ADDSDeployment

Install-ADDSForest 
  -DomainName "lab.local" 
  -DomainNetbiosName "LAB" 
  -SafeModeAdministratorPassword (ConvertTo-SecureString "P@ssw0rd!" -AsPlainText -Force) 
  -InstallDNS:$true -Force
      

After the server reboots it will be a domain controller for lab.local. Ensure the server's DNS service is running and the NIC is configured to use the server's IP as its DNS resolver.

DHCP & DNS Configuration

Option 1 (DHCP on server): install DHCP role and create a scope for your client subnet (e.g., 192.168.50.101–192.168.50.200). Option 2 (static addressing): assign static IPs to clients and use DHCP only if you need dynamic assignment.

# DHCP Role install & scope (PowerShell)
Install-WindowsFeature -Name DHCP -IncludeManagementTools

# Create a scope for 192.168.50.0/24
Add-DhcpServerv4Scope -Name "LabScope" -StartRange 192.168.50.101 -EndRange 192.168.50.200 -SubnetMask 255.255.255.0

# Set DNS server option for the scope (set to DC IP)
Set-DhcpServerv4OptionValue -ScopeId 192.168.50.0 -DnsServer 192.168.50.2
      

Important DNS checks:

  • Ensure the forward lookup zone for lab.local exists and SRV records were created by the DC.
  • Confirm dynamic updates are allowed (default) so client machines register their A records.

Advanced Troubleshooting — PowerShell Recipes

Below are targeted PowerShell scripts and commands to troubleshoot common AD/DNS/DHCP issues. These are copy-paste friendly and color-coded for readability when pasted into WordPress.

1. AD Replication — check replication health

# Check replication status
Get-ADReplicationFailure -Scope Site -Target "lab.local" | Format-Table

# Force replication (example approach)
Get-ADDomainController -Filter * | ForEach-Object {
  Sync-ADObject -Object (Get-ADUser -Filter * | Select -First 1) -Source $_.Name -Destination (Get-ADDomainController -Filter {IsWritable -eq $true}).Name
}

# Use repadmin (classic but effective)
repadmin /replsummary
repadmin /showrepl *
      

2. DNS: verify zones and name resolution

# Check DNS server status
Get-Service -Name DNS

# List zones from server
Get-DnsServerZone -ComputerName 192.168.50.2

# Lookup SRV record for DC
Resolve-DnsName -Name "_ldap._tcp.dc._msdcs.lab.local" -Server 192.168.50.2 -Type SRV
      

3. GPO & SYSVOL issues (common after promotion)

# Verify SYSVOL and NETLOGON shares
Get-SmbShare | Where-Object Name -match "SYSVOL|NETLOGON"

# Check GPO health (exports HTML report)
Get-GPOReport -All -ReportType Html -Path "C:\GPOReport.html"
      

4. DNS cache & client-side checks

# On client (run elevated)
ipconfig /flushdns
ipconfig /registerdns
nltest /dsgetdc:lab.local
nltest /sc_verify:lab\DOMAIN
      

5. AD user & computer quick checks

# Find locked out users
Search-ADAccount -LockedOut

# Check last logon
Get-ADUser -Filter * -Properties LastLogonDate | Sort-Object LastLogonDate -Descending | Select-Object Name,LastLogonDate -First 20
      
Pro tip: run PowerShell as an Administrator and install the RSAT or ActiveDirectory module where needed.

Microsoft Graph API — Automation & Troubleshooting

The Microsoft Graph API can be used to automate Azure AD tasks — useful when your lab extends into Entra ID or hybrid scenarios. Below are examples using the Microsoft Graph PowerShell module and raw REST calls. These examples include colored PowerShell for easy copying into WordPress.

Install Graph PowerShell module & connect (PowerShell)

# Install and connect to Microsoft Graph (run as admin)
Install-Module Microsoft.Graph -Scope CurrentUser -Force
Connect-MgGraph -Scopes "User.ReadWrite.All","Group.ReadWrite.All","Directory.ReadWrite.All"

# Verify connection
Get-MgUser -Top 5
      

Create a user and add to group (Graph PS)

# Create a user
$pwd = "P@ssw0rd!2025" | ConvertTo-SecureString -AsPlainText -Force
$params = @{
  AccountEnabled = $true
  DisplayName = "Lab User"
  MailNickname = "labuser"
  UserPrincipalName = "labuser@contoso.onmicrosoft.com"
  PasswordProfile = @{ ForceChangePasswordNextSignIn = $false; Password = $pwd }
}
New-MgUser -BodyParameter $params

# Create a security group and add member
$g = New-MgGroup -DisplayName "LabAdmins" -MailEnabled:$false -SecurityEnabled:$true -MailNickname "labadmins"
Add-MgGroupMember -GroupId $g.Id -DirectoryObjectId (Get-MgUser -UserId "labuser@contoso.onmicrosoft.com").Id
      

Using raw REST calls (client credentials flow)

Use these steps when building CI/CD pipelines or automation scripts (Python, Bash). You need an App registration with client secret or cert and the right permissions (app-only).

# Example: Acquire token (PowerShell) - Client Credentials
$tenantId = "YOUR_TENANT_ID"
$clientId = "YOUR_APP_ID"
$clientSecret = "YOUR_CLIENT_SECRET"
$body = @{
  client_id = $clientId
  scope = "https://graph.microsoft.com/.default"
  client_secret = $clientSecret
  grant_type = "client_credentials"
}
$token = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" -Method POST -Body $body
$accessToken = $token.access_token

# Use token to call Graph
$headers = @{ Authorization = "Bearer $accessToken" }
Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/users" -Headers $headers -Method GET
      

These Graph calls are especially relevant for hybrid labs where Azure AD Connect is present and you want to sync or automate user lifecycle operations from scripts.

Security Hardening — Make the Lab Realistic

While the lab is isolated, apply these hardening steps to simulate a production environment and practice security operations:

  1. Patch Management: Keep server and clients updated; snapshot before major updates so you can roll back.
  2. Least Privilege: Use non-privileged accounts for daily tasks; create a separate admin account for emergency tasks.
  3. RDP & Remote Access: Disable RDP on domain-joined clients unless needed; restrict RDP via firewall rules.
  4. Account & Password Policies: Implement strong password policies and consider testing Fine-Grained Password Policies in the lab.
  5. Secure LDAP & LDAPS: Practice configuring LDAPS (certificate enrollment) to protect LDAP traffic.
  6. Audit & Event Forwarding: Enable auditing for logons and important AD changes. Forward logs to a collector if testing SIEM scenarios.
  7. Enable Windows Defender & Baselines: Use security baselines (CIS, Microsoft) to harden OS settings and GPOs.

Sample GPO Lockdown (PowerShell)

# Example: enforce password policy via built-in domain policy (modify carefully)
Import-Module GroupPolicy
Set-GPRegistryValue -Name "Default Domain Policy" -Key "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" -ValueName "LimitBlankPasswordUse" -Type DWord -Value 1
      
Practice restoring Active Directory from system state snapshots and AD-aware backups (NTDS.dit and SYSVOL). For disaster recovery training, simulate DC failure and restore sequences.

Testing & Verification — What to validate

After deployment and hardening, verify the following:

  • Clients can resolve lab.local and domain controllers via DNS.
  • Authenticate domain users successfully on clients.
  • AD replication status is healthy between DCs (if multiple DCs exist).
  • DHCP leases are assigned correctly and DNS records are registered for clients.
  • Audit logs reflect administrative operations and user authentications.

FAQs & Common Troubleshooting Scenarios

Q: Client fails to join the domain — what to check?

  1. Ensure client DNS points to the domain controller (not to external DNS).
  2. Check network connectivity (ping DC IP and DNS name).
  3. Verify time sync (Kerberos requires clocks within 5 minutes). Use w32tm /resync.
  4. Check firewall settings on DC and client; disable temporarily to isolate issue.

Q: GPOs not applying?

Run gpupdate /force then gpresult /r on client to see policy application and errors.

Q: SYSVOL or NETLOGON shares missing?

Verify replication and FRS/DFS-R status (depending on your OS). Use Get-SmbShare and examine event logs for DFS-R / SYSVOL errors.

Conclusion & Next Steps

This lab provides a safe environment to learn real-world Active Directory operations and admin workflows. Once comfortable, expand the lab to include:

  • Multiple Domain Controllers across sites (test replication latency & site links)
  • AD Certificate Services for PKI and LDAPS
  • Azure AD Connect for hybrid identity scenarios
  • SIEM integration (e.g., Splunk, Elastic, Defender) for event monitoring

If you want, I can now:

  • Produce exportable PowerShell scripts as downloadable `.ps1` files
  • Generate step-by-step screenshot-ready pages for each major task
  • Create a separate article covering Azure AD Connect & hybrid sync using Graph API automation

Appendix A — Additional PowerShell Utilities

Useful one-liners and small utilities to keep handy in a lab:

# List domain controllers
Get-ADDomainController -Filter *

# Check FSMO role holders
netdom query fsmo

# Get DHCP lease list (server-side)
Get-DhcpServerv4Lease -ComputerName 192.168.50.2 -ScopeId 192.168.50.0

# Export DNS zone to file
Export-DnsServerZone -Name "lab.local" -ComputerName 192.168.50.2 -FileName "C:\lab.local.dns"
      

Appendix B — Quick Microsoft Graph Snippets (REST)

Some practical examples for automating user lifecycle tasks with Graph REST API using token from client credentials flow (see earlier snippet).

# Create User (REST)
$body = @{
  accountEnabled = $true
  displayName = "Lab User REST"
  mailNickname = "labuserrest"
  userPrincipalName = "labuserrest@contoso.onmicrosoft.com"
  passwordProfile = @{ forceChangePasswordNextSignIn = $false; password = "P@ssw0rd!2025" }
} | ConvertTo-Json

Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/users" -Headers $headers -Method POST -Body $body -ContentType "application/json"

# Add a user to a group (REST)
Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/groups/{group-id}/members/$ref" -Method POST -Headers $headers -Body (@{ "@odata.id" = "https://graph.microsoft.com/v1.0/directoryObjects/{user-id}"} | ConvertTo-Json) -ContentType "application/json"
      

Further reading & links

Author: CloudKnowledge Labs • Updated: October 2025
Licensed for lab/educational use. Follow security best practices when moving to production.

Leave a Reply

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