Server · Active Directory

Active Directory: install & first domain — from server to domain controller, without the guesswork

This is a hands-on tutorial that takes one machine from a blank Windows Server installation to a verified first Active Directory domain: the server that can answer logins, the DNS zone that makes it findable, and a first client joined to the domain. It's written for the first time doing it, so every command is explained before you run it, every expected result is stated, and the step where things usually go wrong — promotion — gets the most room.

The whole tutorial runs on one example environment, stated once and used everywhere: a virtual Windows Server 2022 machine named DC01, on an isolated lab network 10.10.20.0/24, creating the example domain example-lab.com. Those values are examples — replace the domain with a name under a domain you actually control, and replace the addresses with your lab's real plan. Anything that must be adapted is marked as you go; nothing here is written for a production network, and a domain controller is never something you point at the public internet.

The DC01 server in a lab: the Server Manager flag notification for the AD DS role, next to the Server Manager window with the new forest options highlighted
Add the hero image at server/active-directory-install-and-first-domain-from-server-to-domain-controller-without-the-guesswork/images/ and set the data-src attribute above. This block hides itself until an image exists.
A first Active Directory domain: clients finding one domain controller A domain controller holds the directory database and runs the domain's DNS server. Domain clients ask DNS where the domain controllers are, find DC01, and authenticate against the directory. A second domain controller can later replicate the directory. CLIENT CLIENT auth / directory DNS query: where are the DCs? DIRECTORY DATABASE DNS SERVER DC ONLINE DC01 · DOMAIN CONTROLLER DC02 (later) replication one forest · one domain · example-lab.com — clients never talk to the directory directly; DNS finds the DC first

Before you touch anything

Understand Active Directory before installation

Active Directory Domain Services (AD DS) is Windows' centralized directory and authentication service. Without it, every machine keeps its own local user accounts: a password set on one PC means nothing on another, and managing ten machines means ten sets of accounts. With it, user accounts, computer accounts, groups, and policies live in one replicated database, and a user signs in once — the domain verifies the identity, and any domain member can trust that verification. A domain controller (DC) is simply a Windows Server machine that runs that database for a domain; a standalone server has none of this and only knows its own local users.

The vocabulary matters from the first click, because the promotion wizard asks about these things by name. A domain is the unit of authentication: one directory partition, one set of accounts, one DNS namespace (our example: example-lab.com). A forest is the top-level security boundary; the first domain you create is the forest root domain, and a simple lab stays at one forest, one domain. Organizational units (OUs) are folders inside the domain where you organize objects and later apply group policy. Directory objects are users, groups, computers, and OUs themselves. And DNS is not an optional accessory — clients locate domain controllers by querying DNS service (SRV) records, so a domain without working internal DNS is a domain no one can find.

The table below is the whole mental model you need for the rest of the article. Everything that follows — the role installation, the promotion, the verification — is just building the rows of this table, in order.

Core Active Directory terms: what each one is and how it relates to the others
TermWhat it isIn this tutorial
DomainOne authentication boundary: a directory partition, a set of accounts, a DNS namespaceexample-lab.com (example)
ForestThe top-level boundary; contains one or more domainsOne — the first domain is its root
Domain controllerA server running AD DS; holds and serves the directory, runs domain DNSDC01
OUA container for organizing objects and applying policyLab (Section 16)
DNSResolves names to addresses; carries the SRV records that point clients at DCsdc01.example-lab.com
Domain functional levelThe oldest Windows Server version whose features the domain will useWindows Server 2022 (Section 12)

One distinction pays off in Section 9, so it's here on purpose: installing the AD DS role and promoting the server to a domain controller are two different operations. The role drops the service binaries and tools onto the machine; the promotion creates the forest and domain, installs the DNS zone, and reboots the server into its new identity. A server with the role installed but not promoted is exactly as useful for directory services as a car with the engine on the floor — so the tutorial never treats "role installed" as "domain working."

The lab

Choose a suitable Windows Server environment

Start from a virtual machine, not real hardware — a domain controller you can snapshot, reset, and destroy is the only safe way to learn promotion. For the edition, any Windows Server 2022 edition works for a lab: Standard and Datacenter differ in virtualization rights and scale licensing, not in AD DS features, so choose whichever your license situation gives you. Choose the Desktop Experience image rather than Server Core for this tutorial: the GUI walkthroughs in Sections 9 and 11 assume a full desktop, and seeing Server Manager is half of learning the tool. (Server Core is the right production choice for many DCs later; the PowerShell paths shown here work identically on Core.)

Resources for a first domain lab are modest. The DC needs 2 vCPUs and 4 GB RAM minimum (give it 8 GB if the hypervisor has headroom), a 60 GB virtual disk, and one virtual network card on a network that is isolated from your real network — in VirtualBox that's an Internal Network, in VMware a custom NAT or host-only network with no internet route. The isolation matters for two reasons: a DC on your home LAN changes its DNS behavior and can break other machines' name resolution if misconfigured, and you will want to destroy this domain at least once without consequence. If you later add a test client VM (Section 17), another 2 vCPUs / 4 GB on the same isolated network is enough.

One source of confusion to kill now: the host and the guest are separate machines with separate settings. A static IP configured in your laptop's network adapter does nothing for the VM; an adapter renamed on the host is invisible to Windows Server. From this point on, "the server" always means the Windows Server VM, and everything you type is typed inside it. The lab plan the rest of the article uses:

Lab hardware and resource plan for the domain controller and optional test client
MachineOSvCPU / RAMDiskNetwork
DC01Windows Server 2022 (Desktop Experience)2–4 vCPUs / 8 GB60 GBIsolated virtual network, 1 NIC
Client01 (Section 17)Windows 10/11 (any recent)2 vCPUs / 4 GB40 GBSame isolated network, 1 NIC

Baseline

Install Windows Server and complete initial setup

Attach the Windows Server 2022 ISO to the VM and boot from it. The installer steps that matter for this tutorial: accept the license terms; choose Custom: Install Windows only (advanced) (there is no upgrade path in a lab); select the virtual disk and let the installer create the partitions — for a fresh 60 GB disk, the default single partition is fine. There is no product key step on the 180-day evaluation image; a licensed image will ask for the key at the edition step. Choose your edition there (Standard or Datacenter, both with Desktop Experience).

Set a strong password for the built-in Administrator account at the end of setup. This is the local administrator of the standalone server — after promotion it becomes the domain's initial Administrator account, so treat this password as a domain credential from day one: complex, not reused from any other account, and noted in your lab password store rather than on a sticky note. Sign in, and Server Manager opens — its red banner will tell you the server has no remote management configured, which is normal and unneeded for a single-machine lab; you can safely dismiss that notification.

Verify you're actually running what you think you're running, because "a Windows that looks server-y" is not a verification. In PowerShell:

PowerShell(Get-CimInstance Win32_OperatingSystem).Caption

Expected: "Microsoft Windows Server 2022 Standard" (or Datacenter) — the edition you chose.

If the caption says Windows 10 or 11, the VM booted the wrong disk and nothing after this point applies to it. That's the only check this section needs; updates, time, and network health are verified in their own sections where a failure would actually matter.

Identity

Rename the server and establish a baseline

A freshly installed server gets a random name like WIN-P3K9D2. You can promote it under that name — Active Directory won't stop you — but a domain is built to be referred to by name for years, and its first machine deserves one: DC01 in this lab. A predictable pattern (DC01, DC02, FILE01) is worth more than a clever name because it survives the day you add machines and start googling your own errors: "DC01" in an event log is instantly locatable, "WIN-P3K9D2" is not. Keep it short — computer names have a 15-character NetBIOS limit that still bites in real environments.

Two ways to do it. GUI: right-click Start → System → Advanced system settings → Computer Name tab → Change…, enter DC01, leave the workgroup as-is (it's irrelevant once the machine joins a domain), and accept the restart prompt. PowerShell (administrative):

PowerShellRename-Computer -NewName DC01 -Force

The cmdlet queues the rename; a reboot applies it.

Either path needs the restart — the machine name is cached by the OS, the TLS/SChannel stack, and other services, so it isn't fully in effect until a reboot. The GUI and PowerShell methods are equivalent in outcome; use the GUI if you like watching things happen, the cmdlet if you'll be scripting a rebuild. After the restart, verify with hostname — it should print exactly DC01. If a later step still shows the old name, check whether the reboot actually happened rather than renaming again.

Network foundation

Configure the network interface and static IP

A domain controller must have a static (or DHCP-reserved) IPv4 address, and the reason is structural, not preference: every client that ever talks to this domain will store this server's IP in its DNS settings, and DNS zone data for the domain is tied to the DC's identity. If the DC's address changed behind the clients' backs, every machine in the domain would quietly lose name resolution at the same moment — a total outage with a boring, avoidable cause. DHCP is fine in the lab for the client VM; for the DC, set the address by hand.

The example network used throughout this article, stated once so every later command is readable: a /24 on 10.10.20.0, gateway 10.10.20.1 (your virtual network's router/NAT device, if it has one — on a purely isolated network with no exit, a gateway is not strictly required, but leave the field consistent with whatever your virtual network provides). Before typing anything: 10.10.20.x is a sample. If your lab uses a different range, use it; and if you do use this range, confirm 10.10.20.10 is unclaimed (a quick ping before configuring) so you don't create an address conflict — duplicate IPs in a lab produce some of the most confusing "nothing works" symptoms there are.

Example IP addressing plan for the lab network, before and after domain controller promotion
MachineIPv4PrefixGatewayDNS (now → after promotion)
DC0110.10.20.10 (static)255.255.255.0 (/24)10.10.20.110.10.20.1 → 127.0.0.1
Client01DHCP (e.g. 10.10.20.30)(from DHCP)(from DHCP)(from DHCP) → 10.10.20.10

Configure it. GUI path: Settings → Network & internet → Ethernet → (your adapter) → Edit (IP assignment) → Manual, switch on IPv4, and enter the table's values. PowerShell, which is less scrolling and easier to verify:

PowerShellGet-NetAdapter | Where-Object Status -eq Up | Select-Object Name, InterfaceDescription, Status New-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress 10.10.20.10 -PrefixLength 24 -DefaultGateway 10.10.20.1 Get-NetIPAddress -InterfaceAlias "Ethernet"

Run in an administrative PowerShell. If the adapter is already on a different address, Remove-NetIPAddress the old one first. The first command exists so you replace "Ethernet" with your adapter's actual alias.

The third command is the verification: it should list 10.10.20.10 with prefix 24 on the adapter. Note what this section deliberately did not do — set DNS. The DC's DNS server settings have two correct values depending on whether it's about to create a domain or join one, and that decision belongs in Section 6 where it's explained properly rather than buried in the IP configuration.

The part that breaks most labs

Configure DNS client settings correctly

The relationship that makes or breaks every first domain: a domain controller is expected to be its own primary DNS server, and its clients point at it. When a Windows client needs to find a domain controller, it doesn't call the DC by address — it asks its configured DNS server for SRV records under the domain (service locators like _ldap._tcp.dc._msdcs.example-lab.com). Those records exist only in the domain's own DNS zone, which the DC hosts. A client pointing at a public resolver like 1.1.1.1 or 8.8.8.8 will happily resolve ordinary websites and fail, every single time, to find the domain — which is why "internet works but the domain doesn't" is the single most common first-domain failure, and it's a DNS-settings problem, not an Active Directory problem.

Now the two-stage nuance that trips people up: the correct DNS setting for this server depends on which side of promotion it's on. Before promotion (right now), the server isn't a DC yet, so pointing it at itself would be wrong — leave it on the lab's current resolver, typically the gateway at 10.10.20.1; it needs working DNS to fetch updates and to reach anything during preparation. After promotion, it must use itself: preferred 127.0.0.1 (the DC's own DNS service) with no public resolver listed as preferred. The promotion wizard actually applies this change for you (Section 13), and if it ever doesn't take, this is the setting to check first. The rule to keep for every machine that will join the domain: its preferred DNS server is the domain controller, full stop.

PowerShellSet-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses ("127.0.0.1") Get-DnsClientServerAddress -InterfaceAlias "Ethernet"

Run these AFTER promotion, if the wizard did not already set it. The Get command should show 127.0.0.1 as Preferred with Automatic = False.

One boundary to state clearly because labs blur it: "don't use public DNS on domain systems" refers to the domain's names — resolving dc01.example-lab.com against 8.8.8.8 will fail or worse. A DC may still need outbound resolution for things like Windows Update; in a richer network that's arranged with conditional forwarders from the domain's DNS to external resolvers. In this isolated lab there's no internet at all, so the question doesn't arise — but the forwarder concept is where this topic goes next in a real environment.

Proof it's ready

Verify time, connectivity, and system health

Three minutes of verification now prevents an hour of promotion debugging later, because the promotion wizard will fail on exactly the conditions this section checks — and its error messages are less legible than the tests below. Run these in an administrative PowerShell and read the expected results as you go:

PowerShellhostname ipconfig /all ping -n 3 10.10.20.1 w32tm /query /status
What each line proves: hostname must read DC01 (Section 4 held). ipconfig /all must show 10.10.20.10/24 on the Ethernet adapter with the gateway you set — and its "DNS Servers" line is your Section 6 "before" state. The ping to the gateway proves layer-3 reachability on the segment; if it fails while other VMs on the same virtual network can ping each other, your static configuration is wrong, and that's a connectivity failure. Finally, w32tm /query /status shows the current time source and last sync — on a standalone server it's usually the local clock with no meaningful source, which is expected now; what you're confirming is only that the command runs and the clock looks sane, because after promotion the DC becomes the domain's time authority and Kerberos authentication tolerates only about five minutes of skew.

Keep the failure taxonomy straight, because Section 18 leans on it: a connectivity failure is "packets don't get there" (ping fails, wrong subnet, adapter down) — fix the network. A resolution failure is "packets get there fine but names don't work" (ping to an IP works, ping to a hostname doesn't, wrong DNS server configured) — fix DNS settings. The two have opposite fixes, and misdiagnosing one as the other is how people restart services that were never the problem. If every line above matches its expectation, the server is ready for the role: correct name, correct address, live network, sane clock.

Pre-flight

Prepare the server for the AD DS role

Preparation has two parts: a state check, and an escape hatch. The state check is short because Sections 4–7 already did the work — confirm, in one place, that the server is on the local Administrators group (you're using the built-in Administrator, so yes), fully updated (Windows Update, then reboot if prompted), named DC01, statically addressed, and DNS-configured per the pre-promotion state. The one condition that must be absent: the server must not already be a domain member or controller (a fresh install isn't — systeminfo shows "Domain: WORKGROUP"-style output; if it shows a domain, you're on the wrong machine or a stale VM).

Server preparation checklist before installing the AD DS role
#CheckHow it was done
1Server named DC01, rebootedSection 4
2Static IPv4, verified with Get-NetIPAddressSection 5
3DNS per pre-promotion state (lab resolver, not itself)Section 6
4Gateway ping OK; time saneSection 7
5Windows Update completeSettings → Windows Update
6Not already a domain member/controllersysteminfo
7VM snapshot taken ("Pre-ADDS")Hypervisor, this section
The escape hatch is the important part for a lab: take a VM snapshot now (VirtualBox: Machine → Take Snapshot; VMware: Snapshot → Take Snapshot), named something you'll recognize like Pre-ADDS. Why a snapshot rather than nothing: promotion is the first step in this tutorial from which you cannot simply "undo" in Windows — a promoted server cannot demote itself with any built-in cmdlet; the supported path out is a fresh install. A snapshot turns "promotion failed halfway" from a several-hour rebuild into a one-click revert, and it makes the rest of the tutorial safe to experiment with. (In production the equivalent is a tested backup — snapshots are a lab tool, not a backup strategy; Section 19 covers the real thing.)

Finally, run the platform's own prerequisite check, which validates that the OS can host AD DS before you commit to anything:

PowerShellTest-InstallADDSForest -DomainName example-lab.com -DomainNetBIOSName EXAMPLELAB -DomainMode Win2022 -ForestMode Win2022

Expected: an object with CanInstall = True. If False, read its Error field — it names the missing condition. Replace the example domain values with your own before running.

That command costs nothing and catches the class of problems the promotion wizard would catch with a less helpful message. CanInstall = True with every checklist row green is the state to start Section 9 from.

Step one of two

Install Active Directory Domain Services

This section installs the role — the binaries, services, and management tools for AD DS — and only that. When it finishes, the server is still a standalone machine; nothing about domains has happened yet. The distinction is worth internalizing because it's the conceptual heart of the whole tutorial: role installation is like adding the engine, promotion (Section 11) is like building the car around it. The two are never the same step, and "I installed AD DS" is never by itself "I have a domain controller."

GUI path: in Server Manager, click the red flag notification ("A new deployment option is available") or go to Manage → Add Roles and Features. Click through Installation Type (Role-based) and Server Selection (the local server is preselected) to the Roles page, check Active Directory Domain Services, and accept the dialog that offers to add the Features (the .NET components the role needs) and the Management Tools And Features (the ADUC/DNS consoles you'll use constantly — always take these). Confirm and wait; the role installs in about a minute. PowerShell path:

PowerShellInstall-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools

Administrative PowerShell. Expected: Success = True, RestartRequired = No.

The two paths produce an identical installed state; the GUI is better for a first pass (you see what's being added), the cmdlet is better for scripted lab rebuilds — after a snapshot revert, one line restores the role instead of four wizard clicks.

Verify the role actually landed, and notice the new artifact:

PowerShellGet-WindowsFeature AD-Domain-Services | Select-Object Name, InstallState

Expected: InstallState = Installed.

Two more confirmations: Server Manager now shows a persistent yellow-flag notification — "Active Directory Domain Services installed. Promote this server to a domain controller" — which is the wizard's front door for Section 11, and Tools → Active Directory Users and Computers now exists in the menu (it will be empty and useless until promotion, which is itself a nice demonstration of role-versus-DC). Role installed, tools present, notification waiting — the machine is ready to be made into something.

The decision that outlives the lab

Understand forests, domains, and domain naming

Promotion has exactly two modes, and picking the wrong one is the most expensive mistake in this tutorial. New forest (Section 11's path): create the first domain of a brand-new forest — correct when the server belongs to no domain at all, which is our fresh VM. Add a domain controller to an existing domain/forest: join a domain that already exists elsewhere — correct only when another DC is already running, and it requires that domain's credentials, working DNS to that domain, and network reachability to the existing DC. If you've been told to "build a domain" and no one has handed you credentials for an existing one, you're creating a new forest; if credentials and a domain name have been handed to you, stop and re-read the task, because promoting into someone else's forest with the wrong settings is a production incident, not a lab exercise.

The domain name is the other decision that's annoying to reverse later — not impossible (domain renaming is a documented but involved migration, not a rename dialog), so get the shape right now. The rules that matter: use a name under a domain you actually control. A lab domain like corp.example — where example is a reserved documentation domain — is safe; a lab domain of acme.com or yourcompany.co.uk that belongs to a real organization is not, because it collides with their real DNS and security boundaries the moment your lab touches the internet, and it trains a bad habit. That's why this article's example is example-lab.com: a subdomain-style name you'd own or that's clearly reserved, used consistently everywhere below. And avoid a bare single-label name (corp with no dot): single-label namespaces collide with Top-Level-Domain behavior in modern resolvers and are a known source of resolution breakage. The name you choose here becomes the domain's DNS zone, the suffix of every computer's FQDN (dc01.example-lab.com), and the container of every user's UPN (user@example-lab.com) — one decision, three permanent surfaces.

Two more fields the wizard will ask about, so they're not surprises in Section 11: the NetBIOS domain name — a short, no-dots legacy identifier (we use EXAMPLELAB) that older tools and some error messages still display, and the DNS root, which for the first domain is simply the domain name itself. Write your three values down now — FQDN, NetBIOS, and the DSRM password you'll choose in Section 12 — because the wizard won't let you go back to change them.

The step

Promote the server to the first domain controller

This is the operation that creates the domain. Concretely, promotion builds the directory partition for your domain, creates the built-in accounts and groups (including the domain Administrator and Domain Admins), installs the DNS zone for the domain on this server, configures the server's network identity as a domain member, writes the initial directory data, and reboots the machine into its new role. Understanding that list explains everything about why it takes minutes rather than seconds, why it ends in a restart, and why Section 13 verifies rather than assumes. The point at which the server becomes a domain controller is the final stage of this process — the reboot — not the role installation you already did.

GUI path (recommended for a first promotion): in Server Manager, click the flag notification → Promote this server. On the first wizard page, choose Add a new forest and enter the root domain name: example-lab.com (yours, per Section 10). Set the Forest and Domain functional levels (Section 12 has the reasoning; for a fresh lab, the top value), and set the Directory Services Restore Mode (DSRM) password — a separate, strong, lab-noted password used only for offline directory repair; the wizard enforces the password policy on it. On the DNS Server options page, for the first domain controller in a new forest there is effectively one correct choice: let it install DNS (it must — the domain needs its zone now), accept the default location for the zones, and decline the delegation (there is no parent zone to delegate from in a new forest; the option is for child domains in existing forests). The subsequent pages are NetBIOS name (EXAMPLELAB), the accounts the DC creates (defaults), and a summary — then Install.

PowerShell path, for scripted or repeatable labs — it encodes the same decisions the wizard made explicit:

PowerShell$dsrm = Read-Host "DSRM password" -AsSecureString $dsrmCred = New-Object System.Management.Automation.PSCredential ("EXAMPLELAB\dsrm", $dsrm) Install-ADDSForest -DomainName "example-lab.com" -DomainNetBIOSName "EXAMPLELAB" ` -DomainMode Win2022 -ForestMode Win2022 -InstallDns:$true -Force ` -SafeModePasswordParameter $dsrmCred

Administrative PowerShell, single line broken for display. Replace the example values. -Force suppresses confirmation (and the auto-restart prompt) — deliberate in a lab. The cmdlet validates prerequisites first and throws with the specific failure if any Section 4–8 condition is missing.

Why both paths exist: the GUI surfaces every decision and its defaults, which is the right way to learn what the promotion is deciding; the cmdlet is idempotent, loggable, and the only option on a Server Core box or in an automated rebuild. They produce the same machine. Whatever path you take, watch the progress stage — it runs the consistency checks, creates the directory, starts DNS, and then the server reboots. If the wizard/cmdlet fails before the reboot, the server is still a standalone machine and you can fix and retry freely; that's the window where the Section 18 matrix is most useful.

The decisions, explained

Configure domain controller and DNS options

Section 11 walked the pages; this section explains the two settings that actually carry weight, so that "accept the defaults" becomes an informed choice rather than a reflex. The functional levels (forest and domain) declare the oldest Windows Server version whose AD features this forest/domain will use. In a brand-new lab where every machine will run current software, choosing the top level (Windows Server 2022) is correct and free — it unlocks the current feature set and the choice is one-way (levels can be raised later, never lowered), which is a non-issue when there's nothing older to protect. In an existing environment, this is the setting to stop and ask an administrator about: a legacy server somewhere may be pinning the forest at an old level, and the promotion options you're allowed will reflect that reality rather than your preference.

Promotion configuration decisions: the setting, the fresh-lab choice, and the existing-environment caution
SettingFresh lab choiceExisting environment
Forest / domain functional levelHighest available (Win2022)Match the existing forest; verify with the administrator
DNS installationInstall (mandatory for first DC)Per the site's DNS design; a DC may host or not host DNS
DNS zone locationDefault (directory-integrated, in the domain partition)Per design; don't move an existing zone
DNS delegationDecline (no parent zone in a new forest)Offer when joining as a child-domain DC with a parent zone
NetBIOS nameShort, no dots (EXAMPLELAB)Must match the existing domain's NetBIOS name exactly
DSRM passwordStrong, unique, stored in the lab password storePer site policy; it is the offline-recovery key for the DC

The DSRM password deserves its own paragraph because it's the setting people set badly and regret in exactly the scenario where regret is most expensive. Directory Services Restore Mode is the offline boot mode used to repair the directory database when normal tools can't run (a corrupted AD database, a DC that won't start its services). That repair requires this password — and it's the only credential that works there; the domain Administrator cannot substitute. So the standard is the same as for any recovery key: complex, unique to this DC, recorded where the rest of the lab's secrets live, and changed if the DC is ever exposed. The wizard's policy check on it isn't nagging; it's the minimum bar for your future offline-recovery option.

Everything else on the promotion pages — the accounts list, the summary — is informational for a first DC: the wizard creates the standard built-in set (Domain Admins, Schema Admins, the DnsAdmins group, the machine account for DC01$, and so on), and there's nothing to customize in a one-domain lab. The one line in the summary to read carefully before clicking Install is the confirmation that you're adding a domain controller to the forest you just named; a surprise existing domain appearing there means this VM is a stale snapshot or the wrong machine, and Install should not happen.

The finish line

Complete promotion and handle the restart

Clicking Install (or the cmdlet running) starts the real work: prechecks, directory creation, DNS zone installation, and the configuration writes, each shown as a stage with its own progress. On the GUI path the final screen tells you the server will restart automatically to complete the configuration — accept it. Total elapsed time in a lab VM is typically a few minutes; the reboot itself is part of the operation, not an interruption. After it comes back, sign in with the account you used before (it's now the domain Administrator; more on the identity change in Section 14) and expect the desktop to look normal — promotion doesn't add visible desktop elements, and "it looks the same" is the correct post-restart observation, not a warning sign.

Confirm success by identity, not by appearance:

PowerShellwhoami (Get-CimInstance Win32_ComputerSystem).Domain systeminfo | Select-String "Domain"

Expected: whoami → example-lab\administrator; the domain field → EXAMPLELAB (NetBIOS). If it still says WORKGROUP, promotion did not complete and you should be reading the next paragraph.

If promotion failed before the reboot, the machine is still standalone — read the wizard's error page or the cmdlet's exception, which names the failing check; Section 18's "promotion errors" row is the working index, and the snapshot (Section 8) is the reset button. If it failed during or after the reboot (the machine came back but whoami shows no domain, or it's looping), the logs to open are: Event Viewer → Applications and Services Logs → Directory Service (the AD DS service's own account of what happened), the ADDS operational log under the same tree, and System for the reboot itself. In a lab, the proportionate move for a badly mangled promotion is revert-to-snapshot and retry with the identified cause fixed — the supported way to demote a domain controller is a fresh install, and a lab exists precisely so that "fresh install" costs one click.

A new kind of account

Sign in using the domain administrator context

Something subtle but real happened to the accounts: the local DC01\Administrator you've been using is still there, but it's no longer the account that matters. Promotion created the domain's example-lab\administrator (the built-in domain Administrator, whose password is the one you set at install time), and that's the identity that carries authority across the domain. The two sign-in forms are equivalent and worth both being able to read: example-lab\administrator (NetBIOS\user — what most tooling and error messages print) and administrator@example-lab.com (user@DNS-domain — the UPN form, what modern sign-in screens prefer). Verify which domain you're actually authenticated to — not just that you're "logged in" — with:

PowerShellwhoami /all | Select-String "User Principal Name|Logon Account"

Expected: the user principal name administrator@example-lab.com and logon account EXAMPLELAB\administrator — domain context, not DC01 (local).

And the handling rules that make the difference between a safe lab and a bad habit: the domain Administrator is a privileged credential, and in this domain it's effectively the keys to everything — every computer, every account, every policy. That's fine for the twenty minutes of this tutorial, and wrong as a daily driver. The pattern to carry forward (and the one Section 16 builds) is: privileged accounts exist to perform administration, then step down; routine work happens under a standard user account that can't damage the domain. Never reuse the domain Administrator's password on any user account, never enter it into anything outside your own lab, and if this were a real domain rather than an isolated VM, the lab-noted password would live in a password manager with access control instead. "It's only a lab" is the exact thought that produces real-world incidents, because the habits are identical.

Proof it works

Verify Active Directory and DNS services

"Role installed" and "directory service functioning" are different claims, and this section exists to make the second one. The verification has three layers — the directory is reachable and reporting sane data, the DNS zone is populated, and name resolution actually works — because a failure at any layer produces symptoms the other layers won't show. Start with the PowerShell queries, which are the fastest complete picture:

PowerShellGet-ADDomain | Select-Object DomainName, DomainNetBIOSName, DomainController, Forest, PDCEmulator Get-ADForest | Select-Object ForestMode, Domains Get-ADDomainController -Identity DC01 | Select-Object HostName, SiteName, IsGlobalCatalog, IsGlobalCatalogEnabled, OperatingSystem

Run on DC01 (the AD module is present on a DC). Expected: domain example-lab.com / EXAMPLELAB; forest with one domain; DC01 listed as PDC emulator and global catalog with a healthy Windows Server 2022 OS line. Any command throwing "cannot find domain" is itself the diagnosis — you're not in the domain context, or the AD module isn't loaded.

Then the GUI layer, because seeing the tree is worth the thirty seconds: Tools → Active Directory Users and Computers should show example-lab.com as the domain root with the Users, Computers, and Builtin containers populated (your user account, the DC01$ computer object, the standard groups). Tools → DNS should show the server node containing example-lab.com with a Zone Transfer-free forward zone holding at least: the _msdcs subdomain, the DC's A record, and the _ldap._tcp SRV records under it — those SRV records are the answer to "where is a domain controller?" that clients have been asking about since Section 1. A missing or empty zone with ADUC working points at the DNS side of the DC, and Section 18's first two rows cover it.

The third layer is resolution, and it's the one clients actually depend on:

PowerShellResolve-DnsName dc01 Resolve-DnsName _ldap._tcp.dc._msdcs.example-lab.com -Type SRV ipconfig /flushdns; Resolve-DnsName example-lab.com

Expected: dc01 resolves to 10.10.20.10; the SRV query returns the DC's record (name DC01.example-lab.com, port 389); the flush + re-resolve proves the answer comes live from the DC's zone, not a stale cache. A name that resolves to the wrong IP is a duplicate-record or stale-cache problem; one that fails to resolve while the zone visibly contains it is a client-DNS-settings problem (Section 6).

All three layers green is the definition of "the first domain works" — and it's also the standing you're in before creating any objects in it. If a layer is red, don't proceed to Sections 16–17 on top of it; the test user and the client join will fail in ways that look like their own bugs while the cause is underneath them.

First real objects

Create a test organizational unit and user

Verification so far has read the directory; this writes to it. OUs exist to organize objects and — later — to be the scope for group policy, so create one deliberately named container rather than dropping users loose in the default Users container (which is a system container, not a home for your objects): Tools → ADUC → example-lab.com → right-click → New → Organizational Unit, name it Lab. Then inside it, right-click Lab → New → User: first name Ad, last Test, user logon name ad.test (which becomes ad.test@example-lab.com as the UPN), and a new password generated specifically for this account — not the Administrator's, not any password in the lab notes, with the "user must change password at next logon" box ticked. That last habit is the point of the section as much as the user is: test accounts are how you'll sign in as a normal person in Section 17, and a test account sharing the admin password would make every subsequent "did the permission work?" question unanswerable.

The PowerShell equivalent, which doubles as the template for creating accounts in any real environment:

PowerShellNew-ADOrganizationalUnit -Name "Lab" $pw = Read-Host "Initial password for ad.test" -AsSecureString New-ADUser -Name "Ad Test" -SamAccountName "ad.test" -UserPrincipalName "ad.test@example-lab.com" ` -Path "DC=example-lab,DC=com" -AccountPassword $pw -ChangePasswordAtLogon $true ` -Enabled $true Get-ADUser ad.test | Select-Object SamAccountName, UserPrincipalName, Enabled, Path

-Path targets the OU by its distinguished name; omit it to land in the default Users container. The final Get is the verification: Enabled = True and Path ending in OU=Lab.

Now the distinction the section is named after: creating a user is not granting any privilege. ad.test can sign in and own nothing — no admin group, no rights beyond default user policy. Privilege in Active Directory is a separate, explicit act (adding the account to Domain Admins, delegating control of an OU, assigning a GPO), and this tutorial deliberately never does it for the test user. If a later task seems to require making ad.test "an admin," that's the moment to pause and ask what right is actually needed — because in a real domain, the gap between "created" and "privileged" is the entire security model.

The first member

Join a test client to the new domain

Bring up Client01 (Section 2's second VM) on the same isolated network. Its one non-negotiable preparation, and the step that fails most joins: its DNS must point at the DC — set the adapter's DNS server to 10.10.20.10 (the DC) as preferred, replacing whatever the virtual network gave it. The join process discovers the domain by DNS, so a client on a public resolver cannot see the domain at all, and the resulting error ("The following error occurred: The specified domain either does not exist or could not be contacted") is a DNS setting problem wearing a domain costume. Verify before joining: ping dc01 from the client should resolve to 10.10.20.10 — if the name fails but the IP pings, you're looking at the exact Section 6 failure, on the client side.

Join it. GUI: Settings → System → About → Domain name (or the classic path: System properties → Change) → Domain → enter example-lab.com → when prompted, credentials of a domain account that may join computers — the domain Administrator (any Domain Admin works; a standard user cannot, and that's the permission boundary doing its job) → accept the invite, reboot when asked. PowerShell (administrative, on the client):

PowerShell$cred = Get-Credential # enter example-lab\administrator when prompted Add-Computer -DomainName "example-lab.com" -Credential $cred -Restart -Force Get-ComputerInfo | Select-Object CsDomain, CsUserName

Add-Computer performs discovery, creates the computer object in the domain's Computers container, and reboots. -Restart -Force makes the reboot part of the command, as the GUI does.

Verify membership the same way Section 13 verified the DC — by identity: after the client reboots, whoami shows the local user with the domain in the session environment, (Get-CimInstance Win32_ComputerSystem).Domain returns EXAMPLELAB, and on the DC side, ADUC → Computers now contains CLIENT01$. The triage that separates client-side from domain-side failures: if the client can't resolve the DC's name, fix the client's DNS (domain is fine); if resolution works but the join is refused with an access error, it's the join account's permissions (client is fine); if the DC itself stopped answering, that's a DC problem and belongs in Section 18. One more first-join success worth taking: sign the client in as ad.test with the Section 16 password — domain authentication for a real standard user, the original point of the whole domain.

When it doesn't

Troubleshoot common first-domain failures

The failures below are the ones that actually happen on first domains, in roughly the order they're encountered, and each row pairs the symptom with the check that discriminates it — because the productive move is identifying which failure, not applying fixes. Use the filter to jump to a symptom class; the diagnostic column is ordered from cheapest to most involved. The general discipline, stated once and used throughout: never restart services or rebuild objects as a first attempt — a service that's "unhealthy" is usually downstream of a DNS or identity problem that restarting would only mask.

First-domain troubleshooting matrix: symptom, likely cause, diagnostic check, and corrective action
SymptomLikely causeCheckFix
Domain name won't resolve; SRV lookups failClient DNS not pointing at the DC; public resolver in useipconfig /all (client) · Resolve-DnsName _ldap._tcp.dc._msdcs.example-lab.com -Type SRVSet the client's DNS to 10.10.20.10, flush, retest. The domain is fine; the client can't see it.
DC resolves its own name but not the domain; zone empty in DNS ManagerDNS zone not created during promotionGet-DnsZone on DC01 · Directory Service event logCheck promotion completed DNS install; if the zone is genuinely missing, the snapshot is the honest reset — re-promote.
Nothing works; other VMs can't reach the DCDuplicate IP on the virtual network; wrong subnetping from another VM · Get-NetIPAddress on DC and neighborsChange the DC to a free address (or the other machine), verify with Get-NetIPAddress, retest.
DC can't reach anything; pings fail one-wayStatic config error: prefix or gatewayipconfig /all · ping gateway vs ping peer separatelyCorrect the /24 or gateway per Section 5. Connectivity failures and DNS failures have opposite fixes — keep them distinct.
Join fails: "domain does not exist or could not be contacted"Client DNS, or no route to the DCping dc01 and ping 10.10.20.10 from the clientName fails but IP works → client DNS (row 1). Both fail → network (rows 3–4). Both work → next row.
Join fails with an access/credential errorAccount used can't join computersConfirm the prompted account is a Domain AdminRetry with the domain Administrator. Standard users can't join — that refusal is the security model working, not a bug.
Promotion fails with a specific error before rebootMissing prerequisite: name, static IP, DNS, existing membershipRead the error text · re-run Test-InstallADDSForest · Section 8 checklistFix the named condition and retry — pre-reboot failure leaves the server standalone, so retry is safe. Snapshot reset if the state is unclear.
Server rebooted but shows no domain (WORKGROUP)Promotion died during/after restartwhoami · Event Viewer → Directory Service and ADDS logsRead the last Directory Service event for the failure point; in a lab, revert to the Pre-ADDS snapshot and re-promote with the cause fixed.
Random Kerberos errors: "clock skew too large", intermittent auth failuresClient clock drifting far from the DCw32tm /query /status on client and DCClient: w32tm /resync /force (it should sync to the DC automatically once joined). DC: verify its own time source. Skew tolerance is ~5 minutes.
ADUC/DNS consoles can't connect; "directory service is unavailable"Active Directory or DNS service stopped on the DCGet-Service "NTDS","DNS" on DC01 · System event logIf a service stopped with a logged cause, address that cause (disk, DNS config) before restarting it. Indiscriminate service restarts on a DC hide the failure instead of fixing it.
Sign-in rejected on the DC; or "password must be changed" loopsLocal vs domain account confusion; first-login password change pendingwhoami /all · which name form is being typedUse the right context: example-lab\administrator for the DC, ad.test for the test user, completing its first-login change. "DC01\administrator" after promotion is the local account — usually not what was intended.
The matrix is a triage tool, not a script: each row's check is designed to confirm the row before its fix is applied, because the most common troubleshooting error is applying the fix for the row you assumed instead of the row the evidence shows.

After it works

Secure, back up, and maintain the new domain controller

The baseline security posture for a DC has few rules and they're all about exposure. Never expose a domain controller to the public internet — no direct WAN IP, no port forwarding to 389/445/88/53, no "quick" remote access through the DC itself; in production it sits behind the network edge and administration reaches it through a controlled path. This lab's isolation network already enforces the right shape; keep it that way, because the moment a DC is internet-reachable with a weak DSRM or admin password, the failure mode is no longer a broken lab. Restrict who can touch it: keep Domain Admins small (in this lab: effectively one person), do routine work as the standard user from Section 16, and don't create "admin2" convenience accounts — every additional privileged account is a permanent standing credential to protect. Keep it updated: Windows Update applies to DCs like any server, but in a real domain you patch DCs deliberately (understood, staged, reversible) rather than on a silent auto-reboot schedule — in this disposable lab, update whenever and reboot without ceremony.

Backup is where the lab/production line matters most, so it's drawn explicitly. The DC's state that must be recoverable is its System State — the directory database, the registry, and the boot files together — because you can't restore "the user ad.test" from a file backup; you restore the DC. On this lab VM, Windows Server Backup → Backup once → System State (or the hypervisor snapshot) is the right level, and the point to internalize is what snapshots are not: a VM snapshot is a rollback convenience, not a tested recovery — in production, the standard is scheduled System State backups, an off-DC copy, and at least one documented restore test, because an untested backup is a hope, not a plan. The DSRM password from Section 12 is the key to the offline end of that recovery chain, which is why it was never allowed to be weak or shared.

Lab versus production: the same control, at different strictness
ControlIn this labIn production
Internet exposureIsolated virtual network (keep it)Never direct; managed remote access path only
Privileged accountsOne admin + one standard test userMinimal Domain Admins; no shared passwords
PatchingAny time, reboot freelyStaged, planned, with rollback understanding
BackupHypervisor snapshot + optional System StateScheduled System State, off-site copy, tested restore
Failure responseSnapshot revert and redoDocumented recovery procedure; demotion = fresh install + re-promote

One maintenance habit that compounds: keep the lab's known-good state honest. After this tutorial, take a final snapshot named something like Working-Domain-v1. Every later experiment — a second DC, a broken join, a policy gone wrong — then has a clean "the domain that worked" to return to, and the difference between a productive lab and a dead one is usually just that one habit.

Done, or not yet

Final validation and next steps

Run the checklist below as the acceptance test for the whole tutorial — every box corresponds to a section's verification, so an unchecked box is a pointer, not a mystery. Your ticks are saved in this browser; copy the list to carry it into your own notes:

ticks are saved in this browser only
If not every box is tickable, the unchecked ones tell you where you are: boxes 1–5 red means the DC itself isn't done (re-enter at that section; Section 18's matrix triages it), boxes 6–8 red means the domain works but hasn't been used yet, which is a shorter gap. "Mostly working" is a real state in Active Directory learning — the skill is knowing which state you're in, and this checklist is built to be that mirror.

What comes next, in a sensible order: join more clients and practice the standard-user daily flow until the local-vs-domain distinction is invisible; add a second domain controller to meet replication and the "one DC is a single point of failure" reality head-on; then group policy, because that's the payoff the whole directory exists to deliver. Those are their own substantial topics and this article deliberately stops at a verified first domain rather than expanding into them. If you'd rather widen the base first — the hardware the DC runs on, or the power and cooling behavior that quietly takes servers down — the guides below cover it.