Establishing a Windows domain has often been a point of contention among administrators. Some advocate for the Graphical User Interface (GUI), while others prefer PowerShell. Personally, I find PowerShell to be a flexible and universal tool, offering advantages over the GUI, especially when aiming for automation and repeatability. This article focuses exclusively on creating and configuring a domain on Windows Server 2022 using PowerShell within a controlled virtual machine environment, demonstrating the potential for automating this fundamental process.
Introduction
Creating a Windows domain remains a key task, sparking debate between GUI devotees and PowerShell proponents. In my view, PowerShell’s flexibility and universality make it superior, particularly for scripting and automation. This guide is dedicated to walking through the creation and configuration of a domain on Windows Server 2022 using only PowerShell, showcasing its power in automating the entire setup within a specific test scenario.
Preparation: Setting Up the Virtual Test Environment
Since creating and configuring a domain controller (DC) can significantly impact your infrastructure, it’s crucial to avoid disrupting a working environment. For this demonstration, I will use a virtual machine (VM) hosted on a Hyper-V server running Windows Server 2022. To verify the domain functionality, a second test VM will act as a client.
As you’ve likely surmised, this test involves two VMs with identical baseline configurations running Windows Server 2022:
- Processors: 2 x vCPU (sufficient for testing)
- RAM: 4 GB
- Storage: 100 GB SSD (or dynamically expanding VHDX)
- Network: Connected via a Hyper-V Private switch to isolate our test network.
The environment scheme for our domain, which we’ll name “Test.com”, includes installing and configuring Active Directory (AD), DNS, and DHCP—three primary services necessary for a functional domain controller.
Here’s the plan for our primary VM, which will become the Domain Controller (DC):
- Hostname: DC01
- Static IP: 172.16.0.10
- Subnet Mask: 255.255.252.0 (which is a /22 prefix)
- Default Gateway: 172.16.0.1 (nominal, as it’s a private network)
- DNS Server: 127.0.0.1 (initially pointing to itself)
- Domain Name: Test.com
The second VM (Test-Client) will initially obtain its configuration via DHCP from DC01.
We will detail each configuration stage performed using PowerShell:
- Initial Server Setup (Rename, Static IP)
- Installing and configuring AD and DNS
- Installing and configuring DHCP
- Checking the status of the services on the domain client
- Automating the entire process with a script
1. Initial Server Setup (DC01 VM)
Initially, some tasks require the GUI, such as logging into the fresh OS installation on the DC01 VM and starting PowerShell. After logging in, press Win+R, type powershell, and click OK, or right-click the Start button and choose “Windows PowerShell (Admin)” or “Windows Terminal (Admin)”. Ensure you run PowerShell with administrative privileges for these tasks.
Renaming the Server
The first task is renaming the machine to match our environment scheme (DC01).
PowerShell
Rename-Computer -NewName "DC01" -Restart
This command renames the server to “DC01”. The -Restart parameter ensures the server restarts immediately to apply the changes. Renaming before installing AD DS prevents potential conflicts.
Configuring a Static IP Address
Upon restarting, log in again and open PowerShell (Admin). First, identify the network adapter’s name.
PowerShell
Get-NetAdapter
Note the name (often “Ethernet” or similar). Now, assign the static IP address, subnet mask, and default gateway according to our plan. Remember, for our private network, the gateway address (172.16.0.1) is nominal. The -PrefixLength 22 corresponds to the subnet mask 255.255.252.0.
PowerShell
New-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress "172.16.0.10" -PrefixLength 22 -DefaultGateway "172.16.0.1"
(Replace “Ethernet” with your actual adapter name if different)
Next, configure the DNS server address. For a single domain controller setup like this, setting the primary DNS server address to the loopback interface (127.0.0.1) is standard practice initially. It ensures the server looks to itself for DNS resolution once the DNS role is installed. We’ll leave the secondary empty for now.
PowerShell
Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses "127.0.0.1"
(Replace “Ethernet” with your actual adapter name if different)
A static IP and correct DNS settings are essential for AD functionality.
2. Installing and Configuring AD and DNS
Now, proceed to install the necessary services: Active Directory Domain Services (AD DS) and DNS.
Install AD DS and DNS Roles
Use the Install-WindowsFeature cmdlet to install both roles, including their management tools.
PowerShell
Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools
Install-WindowsFeature -Name DNS -IncludeManagementTools
PowerShell will show the installation progress. This might take a few minutes. AD DS provides the core directory services, while DNS is crucial for name resolution within the domain. Installing them together on the first DC is typical for simpler environments.
Promote the Server to a Domain Controller
After installing the roles, the next step is to promote the server (DC01) to become the first domain controller in a new forest (Test.com).
Use the Install-ADDSForest cmdlet. You’ll need to provide the domain name and a password for the Directory Services Restore Mode (DSRM). Choose a strong, unique password for DSRM and store it securely.
PowerShell
# Define a secure string for the DSRM password
$DSRMPassword = ConvertTo-SecureString "YourStr0ngDSRMP@sswOrd!" -AsPlainText -Force
# Install the new Forest
Install-ADDSForest -DomainName "Test.com" -SafeModeAdministratorPassword $DSRMPassword -InstallDNS -Force
- -DomainName “Test.com” specifies our chosen domain name.
- -SafeModeAdministratorPassword $DSRMPassword sets the DSRM password using the secure string.
- -InstallDNS delegates DNS installation and configuration for the new domain.
- -Force can be used to automatically confirm prompts, including the final reboot.
The promotion process configures AD, sets up DNS zones for Test.com, and makes this server the authority for the domain. The server will restart automatically after the promotion completes.
Post-Promotion Verification
Upon restarting, you should notice the domain (TEST\) as part of the login prompt, indicating AD is active. Log in using the domain administrator account (e.g., TEST\Administrator) with the password you set during Windows Server installation.
Open PowerShell (Admin) again and perform some checks:
Verify the domain and forest status:
PowerShell
Get-ADDomain
Get-ADForest
Check the DNS server status and ensure the Test.com zone exists:
PowerShell
Get-DnsServerZone -Name "Test.com"
Verify the server role:
PowerShell
Get-ComputerInfo | Select-Object -Property OsRoles
You should see “Domain Controller” listed.
Additionally, it’s wise to check the AD-related event logs (Directory Service, DNS Server, DFS Replication) for any critical errors before proceeding.
3. Installation and Configuration of DHCP
With AD and DNS running, let’s install and configure the DHCP service on DC01 to provide IP addresses to clients like our Test-Client VM.
Install DHCP Role
PowerShell
Install-WindowsFeature -Name DHCP -IncludeManagementTools
Configure DHCP Scope and Options
We need to define an address pool (scope) for automatic allocation. Let’s use the range 172.16.1.1 to 172.16.1.254 within our /22 subnet. We also need to tell DHCP clients what the DNS server and gateway are.
PowerShell
# Define the scope details
$ScopeName = "TestNetworkScope"
$ScopeId = "172.16.0.0" # Network ID for the /22 scope
$StartRange = "172.16.1.1"
$EndRange = "172.16.1.254"
$SubnetMask = "255.255.252.0" # /22
$LeaseDuration = New-TimeSpan -Days 8 # Standard lease time
# Add the scope
Add-DhcpServerv4Scope -Name $ScopeName -StartRange $StartRange -EndRange $EndRange -SubnetMask $SubnetMask -LeaseDuration $LeaseDuration -State Active
# Set DHCP options for the scope: DNS Server and Router (Gateway)
$DnsServerIP = "172.16.0.10" # Our DC's IP
$RouterIP = "172.16.0.1" # Our nominal gateway IP
Set-DhcpServerv4OptionValue -ScopeId $ScopeId -OptionId 6 -Value $DnsServerIP # Option 6 = DNS Servers
Set-DhcpServerv4OptionValue -ScopeId $ScopeId -OptionId 3 -Value $RouterIP # Option 3 = Router
Authorize DHCP in Active Directory
DHCP servers in an AD environment must be authorized to operate.
PowerShell
Add-DhcpServerInDC -DnsName DC01.Test.com -IPAddress 172.16.0.10
(Using FQDN is best practice here)
Restart the DHCP Service
Apply the configuration changes by restarting the DHCP service.
PowerShell
Restart-Service DhcpServer
Congratulations, the DHCP configuration on DC01 should now be complete!
4. Perform the Services Health Check on the Domain Client (Test-Client VM)
Now, let’s verify that our domain services are working from the perspective of a client machine.
Start and Check the Client VM
Start the Test-Client VM. Since it’s connected to the same Hyper-V Private switch as DC01, it should automatically contact the DHCP server. If you see a network connection established quickly, it’s a good sign.
Log into the Test-Client VM, open PowerShell (Admin), and check its network configuration:
PowerShell
Get-NetIPConfiguration
Verify that it received an IP address from the 172.16.1.x range, the correct subnet mask (255.255.252.0), the gateway (172.16.0.1), and crucially, the DNS server address pointing to our DC (172.16.0.10).
Rename and Join the Client to the Domain
First, give the client a meaningful name, say Client01.
PowerShell
Rename-Computer -NewName "Client01" -Restart
After the client restarts, log back in, open PowerShell (Admin), and join it to the Test.com domain.
PowerShell
Add-Computer -DomainName "Test.com" -Credential (Get-Credential) -Restart
- -DomainName “Test.com” specifies the domain to join.
- -Credential (Get-Credential) will trigger a standard Windows pop-up window asking for credentials with rights to join computers to the domain (e.g., TEST\Administrator and its password).
- -Restart automatically reboots the client after successfully joining the domain.
Final Client Verification
After the client restarts, you should be able to log in using a domain account (e.g., TEST\Administrator). Open PowerShell and verify network settings again to confirm it retains the correct configuration.
Check domain connectivity:
PowerShell
Test-ComputerSecureChannel -Verbose
This should return True if the secure channel to the domain controller is operational.
Verify DNS settings specifically:
PowerShell
Get-DnsClientServerAddress -InterfaceAlias "Ethernet" # Use your client's adapter name
Ensure it still points to 172.16.0.10.
5. Automating the Entire Process with PowerShell Script
While the step-by-step approach is useful for understanding, the real power of PowerShell comes from automation. Combining these steps into a single script allows for rapid, consistent, and error-reduced deployment, especially valuable in VM environments.
Creating the Comprehensive Script
Below is a script that encapsulates the setup for our DC01 VM. It defines variables upfront for easy modification.
Important Considerations Regarding Reboots:
- The Rename-Computer cmdlet includes the -Restart parameter.
- The Install-ADDSForest cmdlet will trigger a reboot upon completion.
- A single PowerShell script running locally cannot automatically continue after a system reboot.
Therefore, this script is presented conceptually. For practical execution, you would typically: a) Run the script in parts, manually initiating the next part after each reboot. b) Remove the -Restart flags and manually reboot when required. c) Use more advanced orchestration tools (like PowerShell DSC, Task Scheduler with triggers, or deployment software) that can manage multi-stage processes involving reboots.
Here is the consolidated script, annotated with comments about the necessary breaks for reboots:
PowerShell
<#
.SYNOPSIS
Automates the setup of a Windows Server 2022 Domain Controller (AD DS, DNS, DHCP)
in a predefined VM environment.
.DESCRIPTION
This script performs the following actions:
1. Renames the server. (Requires Reboot)
2. Configures a static IP address and DNS settings.
3. Installs AD DS, DNS, and DHCP roles.
4. Promotes the server to a Domain Controller in a new forest. (Requires Reboot)
5. Configures a DHCP scope and authorizes the DHCP server.
6. Performs basic verification checks.
.NOTES
– Run this script with Administrator privileges.
– !! IMPORTANT !! This script includes steps that require server reboots.
You MUST run this script in stages manually, restarting the server
after the Rename-Computer step and after the Install-ADDSForest step.
– Modify the variables in the “Define Variables” section to match your environment.
– Test thoroughly in a non-production environment first.
#>
#Requires -Version 5.1
#Requires -RunAsAdministrator
# — Define Variables —
$NewServerName = “DC01”
$InterfaceAlias = “Ethernet” # Verify with Get-NetAdapter
$StaticIPAddress = “172.16.0.10”
$PrefixLength = 22 # Corresponds to 255.255.252.0
$DefaultGateway = “172.16.0.1”
$LoopbackDns = “127.0.0.1”
$DomainName = “Test.com”
$DSRMPasswordPlainText = “YourStr0ngDSRMP@sswOrd!” # Change this!
$DhcpScopeName = “TestNetworkScope”
$DhcpScopeId = “172.16.0.0” # Network ID for the /22 scope
$DhcpStartRange = “172.16.1.1”
$DhcpEndRange = “172.16.1.254”
$DhcpSubnetMask = “255.255.252.0”
$DhcpLeaseDuration = New-TimeSpan -Days 8
$DhcpRouterIP = $DefaultGateway
$DhcpDnsServerIP = $StaticIPAddress
# Convert DSRM Password to SecureString
$DSRMPassword = ConvertTo-SecureString $DSRMPasswordPlainText -AsPlainText -Force
Write-Host “Starting Domain Controller Setup Script…” -ForegroundColor Yellow
# — Stage 1: Rename Server (Requires Manual Restart After This Section) —
Write-Host “— Stage 1: Renaming Server —”
try {
$currentName = (Get-ComputerInfo).CsName
if ($currentName -ne $NewServerName) {
Write-Host “Renaming server to $NewServerName and initiating restart…” -ForegroundColor Cyan
Rename-Computer -NewName $NewServerName -Force -Restart
Write-Host “Server renaming initiated. Please wait for reboot and then manually run the remainder of the script.” -ForegroundColor Green
# Script execution will stop here due to reboot.
} else {
Write-Host “Server name is already set to $NewServerName.” -ForegroundColor Green
}
} catch {
Write-Host “Error renaming server: $($_.Exception.Message)” -ForegroundColor Red
exit 1
}
# — !!! MANUAL RESTART REQUIRED HERE !!! —
# — After restarting and logging back in, run the script again, or run the remaining sections manually —
# — For simplicity in demonstration, the rest of the script assumes it’s run *after* the first reboot —
Write-Host “— Continuing Script After First Reboot —” -ForegroundColor Yellow
# — Stage 2: Configure Static IP —
Write-Host “— Stage 2: Configuring Static IP Address —”
try {
Write-Host “Setting Static IP: $StaticIPAddress / $PrefixLength, Gateway: $DefaultGateway” -ForegroundColor Cyan
Get-NetAdapter -Name $InterfaceAlias | New-NetIPAddress -IPAddress $StaticIPAddress -PrefixLength $PrefixLength -DefaultGateway $DefaultGateway -ErrorAction Stop
Write-Host “Setting DNS Server to Loopback: $LoopbackDns” -ForegroundColor Cyan
Get-NetAdapter -Name $InterfaceAlias | Set-DnsClientServerAddress -ServerAddresses $LoopbackDns -ErrorAction Stop
Write-Host “Static IP and initial DNS configured successfully.” -ForegroundColor Green
} catch {
Write-Host “Error configuring static IP address: $($_.Exception.Message)” -ForegroundColor Red
# Consider if you want to exit here depending on error handling strategy
# exit 1
}
# — Stage 3: Install Roles (AD DS, DNS, DHCP) —
Write-Host “— Stage 3: Installing AD DS, DNS, and DHCP Roles —”
$roles = @(“AD-Domain-Services”, “DNS”, “DHCP”)
foreach ($role in $roles) {
try {
Write-Host “Installing role: $role…” -ForegroundColor Cyan
Install-WindowsFeature -Name $role -IncludeManagementTools -ErrorAction Stop
Write-Host “$role installed successfully.” -ForegroundColor Green
} catch {
Write-Host “Error installing role $role: $($_.Exception.Message)” -ForegroundColor Red
# Consider exiting if critical roles fail
# exit 1
}
}
# — Stage 4: Promote to Domain Controller (Requires Manual Restart After This Section) —
Write-Host “— Stage 4: Promoting Server to Domain Controller —”
try {
Write-Host “Promoting server to Domain Controller for domain $DomainName…” -ForegroundColor Cyan
Install-ADDSForest -DomainName $DomainName `
-SafeModeAdministratorPassword $DSRMPassword `
-InstallDNS `
-Force `
-ErrorAction Stop
Write-Host “Domain Controller promotion initiated. Server will restart automatically.” -ForegroundColor Green
# Script execution effectively stops here for the local machine due to reboot.
} catch {
Write-Host “Error promoting server to domain controller: $($_.Exception.Message)” -ForegroundColor Red
exit 1
}
# — !!! SERVER WILL RESTART AUTOMATICALLY HERE !!! —
# — After restarting and logging in as DOMAIN Admin, run the remaining sections manually or via a separate script —
# — For simplicity, the rest assumes it’s run *after* the promotion reboot —
Write-Host “— Continuing Script After Promotion Reboot —” -ForegroundColor Yellow
# — Stage 5: Configure DHCP —
Write-Host “— Stage 5: Configuring DHCP Scope and Authorization —”
try {
Write-Host “Adding DHCP Scope: $DhcpScopeName ($DhcpStartRange – $DhcpEndRange)” -ForegroundColor Cyan
Add-DhcpServerv4Scope -Name $DhcpScopeName `
-StartRange $DhcpStartRange `
-EndRange $DhcpEndRange `
-SubnetMask $DhcpSubnetMask `
-LeaseDuration $DhcpLeaseDuration `
-State Active `
-ErrorAction Stop
Write-Host “Setting DHCP Options for Scope $DhcpScopeId (DNS: $DhcpDnsServerIP, Router: $DhcpRouterIP)” -ForegroundColor Cyan
Set-DhcpServerv4OptionValue -ScopeId $DhcpScopeId -OptionId 6 -Value $DhcpDnsServerIP -ErrorAction Stop # DNS Servers
Set-DhcpServerv4OptionValue -ScopeId $DhcpScopeId -OptionId 3 -Value $DhcpRouterIP -ErrorAction Stop # Router
$fqdn = (Get-ComputerInfo).CsDNSHostName
Write-Host “Authorizing DHCP Server $fqdn in Active Directory…” -ForegroundColor Cyan
Add-DhcpServerInDC -DnsName $fqdn -IPAddress $StaticIPAddress -ErrorAction Stop
Write-Host “Restarting DHCP Service…” -ForegroundColor Cyan
Restart-Service DhcpServer -ErrorAction Stop
Write-Host “DHCP configuration completed successfully.” -ForegroundColor Green
} catch {
Write-Host “Error during DHCP configuration: $($_.Exception.Message)” -ForegroundColor Red
# Decide if failure here is critical
}
# — Stage 6: Final Verification —
Write-Host “— Stage 6: Performing Final Verification Checks —”
try {
Write-Host “Verifying AD Domain…” -ForegroundColor Cyan
Get-ADDomain -ErrorAction Stop | Select-Object Name, DomainMode, Forest | Format-List
Write-Host “Verifying DNS Zone…” -ForegroundColor Cyan
Get-DnsServerZone -Name $DomainName -ErrorAction Stop | Select-Object ZoneName, ZoneType, IsDsIntegrated | Format-List
Write-Host “Verifying Server Roles…” -ForegroundColor Cyan
Get-ComputerInfo | Select-Object -ExpandProperty OsRoles
Write-Host “Verifying DHCP Scope…” -ForegroundColor Cyan
Get-DhcpServerv4Scope -ScopeId $DhcpScopeId -ErrorAction Stop | Format-List ScopeId, Name, State, StartRange, EndRange
Write-Host “Verification checks completed.” -ForegroundColor Green
} catch {
Write-Host “Error during final verification: $($_.Exception.Message)” -ForegroundColor Red
}
Write-Host “Domain Controller Setup Script finished.” -ForegroundColor Yellow
Executing the Script
- Save the script content to a file named something like Setup-DC.ps1 on the server that will become DC01.
- Open PowerShell as Administrator.
- Navigate to the directory where you saved the script using cd C:\Path\To\Script.
- Execute the first part: .\Setup-DC.ps1
- Wait for the server to rename and restart.
- Log back into the server. Open PowerShell as Administrator again.
- Re-run the script: .\Setup-DC.ps1. It should detect the name is correct and proceed with IP config, role install, and promotion.
- Wait for the server to promote and restart automatically.
- Log back into the server using the domain administrator account (e.g., TEST\Administrator). Open PowerShell as Administrator.
- Re-run the script: .\Setup-DC.ps1. It should now configure DHCP and run verification checks.
Always test automation scripts thoroughly in a dedicated lab or test environment before using them in production.
Conclusions
Using PowerShell to configure a Windows Server 2022 domain, even in a simple VM test environment like this one based on Test.com, provides a robust, repeatable, and efficient method. Whether executed step-by-step for learning or via a script for automation, PowerShell streamlines the setup of AD, DNS, and DHCP, ensuring consistency.
The combination of these three services is essential for a functional domain, and verifying their status on both the server and a client confirms network stability. Automating this process with PowerShell not only significantly reduces the time required for configuration compared to clicking through the GUI but also minimizes the potential for human errors.
This guide serves as a solid foundation. From here, you could script the addition of more domain controllers, implement Group Policy Objects (GPOs), configure users and groups, and further secure the environment — all leveraging the power of PowerShell.