Deploy Your First Active Directory Forest and Domain

  • 6/29/2015

Deploy your first forest

Most Windows system administrators will probably never have to create a new forest in an environment where there has never been one before. Most of us join a company and an environment that has been up and running for some time, and our tasks are focused on maintaining that existing environment—adding users and groups, adding domain controllers to existing domains, and even adding new domains to an existing forest. I’ll cover all of those tasks in this book, and you can certainly jump ahead to the chapter that covers what you want to accomplish. But for those who are tasked with creating a new environment, it’s important to do the job right, and that means planning first

This is not a book on how to plan a new namespace and Active Directory forest. Instead of covering that here, I suggest that you read Chapters 3 and 4 of Windows Server 2008 Administrator’s Companion (Microsoft Press, 2008). Yes, it’s been a while since I wrote those chapters, but they’re still valid today and will give you a solid understanding of the process.

Before you begin, make sure you have identified all the elements you’ll need to configure as you set up the server you’ll use to create your new forest and domain, and what the values for those are. The exact list you’ll need will vary depending on the results of the preliminary planning you’ve done, and your network configuration, but it will likely include at least the following:

  • Server IP address
  • Server name
  • Domain Name System (DNS) namespace for the root domain of the new forest
  • Domain name for the root domain of the new forest
  • DNS server type (Active Directory–integrated, or stand-alone)

A comment here about the server IP address: your domain controllers should ideally all use static IP addresses, but definitely your first domain controller should be at a fixed IP address.

Configure the server IP address

You can configure the server’s name before the IP address, but when you do, it costs an extra reboot because the name change requires a reboot, so I like to do the IP address first. Setting a fixed IP address for a computer requires four commands—one to get the name and index of the network adapter you’re setting to a fixed IP address, and three to configure the settings for that adapter.

Get the adapter alias and index

Before you can configure new settings for a network adapter, you need to know either the adapter’s interface alias (name) or interface index. The interface alias corresponds to the name shown in the Network Connections dialog box (ncpa.cpl). To determine the interface alias and interface index, use the Get-NetAdapter cmdlet.

Name        InterfaceDescription    ifIndex Status      MacAddress         LinkSpeed 
----        --------------------    ------- ------      ----------          --------- 
10 Network  Microsoft Hyper-V              
            Network Adapter #2      4       Up          00-15-5D-32-10-02    10 Gbps
50 Network  Microsoft Hyper-V  
            Network Adapter         3       Disabled    00-15-5D-32-50-02    1 Gbps

The default output from Get-NetAdapter uses the Name column for the InterfaceAlias property and the ifIndex column for the InterfaceIndex property. To view all the properties and the actions associated with Get-NetAdapter, use the following.

Get-NetAdapter | Get-Member

Set a fixed IP address

To set a fixed IP address for this first domain controller in the forest, you need to first disable Dynamic Host Configuration Protocol (DHCP) and then set the IPv4 and IPv6 addresses. For the lab network used in this book, I have chosen as the IPv4 subnet, and 2001:db8:0:10::/64 as the IPv6 subnet.

To disable DHCP on the 10 Network adapter, use the following command.

Set-NetIPInterface -InterfaceAlias “10 Network” -DHCP Disabled -PassThru

The Set-NetIPInterface cmdlet is a quiet cmdlet that doesn’t return anything by default, so I added the -PassThru parameter to have it report back on the status of the IP interface.

Next, set the static IPv4 address to by using the following command.

New-NetIPAddress ` 
     -AddressFamily IPv4 ` 
     -InterfaceAlias “10 Network” ` 
     -IPAddress ` 
     -PrefixLength 24 ` 

Now set the IPv6 address to 2001:db8:0:10::2 by using the following command.

New-NetIPAddress ` 
     -AddressFamily IPv6 ` 
     -InterfaceAlias “10 Network” ` 
     -IPAddress 2001:db8:0:10::2 ` 
     -PrefixLength 64 ` 
     -DefaultGateway 2001:db8:0:10::1

The New-NetIPAddress cmdlet automatically selects the IPv4 or IPv6 address family based on the settings in the command, so you can omit the -AddressFamily parameter from the preceding commands if you want.

Set the DNS server addresses

The last part of setting a fixed IP address is to set the DNS server addresses. Because your first domain controller in the new forest should also be your DNS server, that’s pretty easy to do by using the Set-DnsClientServerAddress cmdlet.

Set-DnsClientServerAddress ` 
     -InterfaceAlias “10 Network” ` 

So, when you pull all that together and run it on the first domain controller in your new forest, you can then run Get-NetIPAddress and get something like the following.

Get-NetIPAddress -InterfaceAlias “10 Network”
IPAddress         : 2001:db8:0:10::2 
InterfaceIndex    : 4 
InterfaceAlias    : 10 Network 
AddressFamily     : IPv6 
Type              : Unicast 
PrefixLength      : 64 
PrefixOrigin      : Manual 
SuffixOrigin      : Manual 
AddressState      : Preferred 
ValidLifetime     : Infinite ([TimeSpan]::MaxValue) 
PreferredLifetime : Infinite ([TimeSpan]::MaxValue) 
SkipAsSource      : False 
PolicyStore       : ActiveStore 
IPAddress         : 
InterfaceIndex    : 4 
InterfaceAlias    : 10 Network 
AddressFamily     : IPv4 
Type              : Unicast 
PrefixLength      : 24 
PrefixOrigin      : Manual 
SuffixOrigin      : Manual 
AddressState      : Preferred 
ValidLifetime     : Infinite ([TimeSpan]::MaxValue) 
PreferredLifetime : Infinite ([TimeSpan]::MaxValue) 
SkipAsSource      : False 
PolicyStore       : ActiveStore

Set the server name

Before you actually deploy your new forest, you should set the name of your domain controller to match your naming convention. Changing the name of a computer causes a reboot, which is why you should delay that change until after all the IP address setting is done. To change the name of the new server to trey-dc-02, use the Rename-Computer cmdlet by using the following syntax.

Rename-Computer -NewName trey-dc-02 -Restart -Force -PassThru

This changes the name of the server and automatically restarts it. The -Force parameter suppresses the confirmation prompt, and the -PassThru parameter returns the results of the command. After the server restarts, you’re ready to actually deploy your forest.

Install Active Directory Domain Services

Before you can promote the server to be a domain controller, you need to install the Active Directory Domain Services role on the server. Installing a role or feature uses the Install-WindowsFeature cmdlet. This cmdlet replaces the Add-WindowsFeature cmdlet used in Windows Server 2008 R2. For compatibility, Add-WindowsFeature is an alias to Install-WindowsFeature. The command to install AD DS, including the management tools required, is as follows.

Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools

This installs AD DS on the server and includes both the graphical and Windows PowerShell tools that are used to manage and deploy Active Directory. For the purposes of this book, this includes two Windows PowerShell modules—ActiveDirectory and ADDSDeployment.

Create the forest (dcpromo)

Beginning with Windows Server 2000, and right up until Windows Server 2012, the command-line way to create a new domain controller was to use the dcpromo command. But beginning with Windows Server 2012, dcpromo has been replaced with the ADDSDeployment module. This module supports remoting so that you can promote a server to a domain controller, create a new domain, or even create a new forest, without logging on to the server that is being promoted. To view the cmdlets in this module, use the following syntax.

Get-Command -Module ADDSDeployment | Format-Table Name

As you can tell, almost all of the various promote/demote/test possibilities are included in the module. The five Test cmdlets need a bit of explanation. Each of these cmdlets allows you to actually test whether all prerequisites are met before you run the Install or Add cmdlet of the same noun. This way you can fully test your environment before committing. The Install and Add nouns actually perform these same tests and will error out if any of them fail. However, the time to find out that you’ve got a problem is not the weekend you’re actually performing the installation, but well before, so that you can correct any deficiencies and be prepared for success.

Update Windows PowerShell help

Before you go any further, it’s a good idea to update your Windows PowerShell help files. Unfortunately, there are only stub help files (man pages) included with Windows PowerShell. This allows Microsoft to update the help files on a regular basis, but it isn’t terribly helpful if you’re using an unfamiliar command. The only full help file included with Windows PowerShell is that for the Update-Help cmdlet.

You need to be running with Administrative privileges to update the help files. You can update directly from Microsoft (the default) or update from a network share. The basic command is the following.


Yes, it is just that simple. This downloads and installs help files for all modules in the current session and for any modules found in the $PSModulePath locations. If you run it on a computer that already has the help files installed, it will check the current version against the updated version and install only those that are new. You can install help files from a network share by using the -SourcePath parameter:

Update-Help -SourcePath \\trey-dc-02\PSHelp

It’s a good idea to get in the habit of updating help files whenever you add new modules to a server. If you have servers that don’t have Internet access, or if you just want to control your Internet bandwidth, you can use the Save-Help cmdlet to download and save the newest help files to a network share. The command to force an update to the current help files and then save them to the \\trey-dc-02\PSHelp share is the following.

Save-Help -DestinationPath \\trey-dc-02\PSHelp -force

Test the forest creation

Before you start your weekend forest creation, only to discover in the middle of the process that you don’t have the necessary prerequisites, it’s a good practice to use the appropriate Test cmdlet to verify your environment. For creating the first forest in this book, that means using the Test-ADDSForestInstallation cmdlet. To test the trey-dc-02 server, which is sitting in a completely isolated lab environment and has no DNS on the network, use the Test-myForestCreate.ps1 script.

Import-Module ADDSDeployment 
Test-ADDSForestInstallation ` 
     -DomainName '’ ` 
     -DomainNetBiosName 'TREYRESEARCH’ ` 
     -DomainMode 6 ` 
     -ForestMode 6 ` 
     -NoDnsOnNetwork ` 

This script imports the ADDSDeployment module into the current session and then tests the environment to find out whether installing the new forest will succeed. (And before I get comments—yes, I know that the Import-Module step is no longer required. But it’s a good habit from the old days to explicitly load a nonstandard module when I know I’m going to need it.) The results of the test are shown in Figure 1-1.

Figure 1-1

Figure 1-1 The results of Test-myForest.ps1

As you can tell, the Test-ADDSForestInstallation cmdlet returns two warnings. One is about the security settings; it warns about compatibility with some older versions of Windows NT due to a change in the cryptography. This is normal and expected, and it can be ignored unless you have computers or devices on your network that require settings that are compatible with Windows NT 4.0. The second is a delegation warning for DNS. This is also expected in most cases. Neither warning is sufficient to stop the installation or create problems, so you’re ready to proceed.

Deploy the first domain controller and forest

At this point, you’ve configured your server, added the necessary Windows PowerShell modules and the Windows Server roles, and tested your environment. All is ready to do the actual initial deployment of your first domain controller and root AD DS forest.

The actual command to install the new forest and domain is nearly identical to the Test-ADDSForestInstallation command in the Test-myForest script. The main difference is that this time, you do want to reboot the server when the installation is finished, and because you just ran the tests, you can skip them.

Install-ADDSForest ` 
     -DomainName '’ ` 
     -DomainNetBiosName 'TREYRESEARCH’ ` 
     -DomainMode 6 ` 
     -ForestMode 6 ` 
     -NoDnsOnNetwork ` 
     -SkipPreChecks ` 

The other thing added here is a -Force parameter to suppress any confirmation prompts. You’ll still be prompted for the value of the Directory Services Restore Mode (DSRM) password. You can avoid even that by using the -SafeModeAdministratorPassword parameter with a SecureString value equivalent to your password. If you’re automating a lot of forest (or domain) creations, such as in a lab environment, use this syntax to set the DSRM password to a value of P@ssw0rd!.

$pwdSS = ConvertTo-SecureString -String 'P@ssw0rd!’ -AsPlainText -Force

The acceptable values for ForestMode and DomainMode are shown in Table 1-1.

Table 1-1 Acceptable DomainMode and ForestMode values

Functional level



Windows Server 2003



Windows Server 2008



Windows Server 2008 R2



Windows Server 2012



Windows Server 2012 R2



The default forest functional level for Windows Server is typically the same as the Windows Server version, with the exception that the default for Windows Server 2008 R2 is a forest functional level of Windows Server 2003.

The domain functional level can never be less than the forest functional level, but it can be higher. If the DomainMode isn’t specified, it is computed from the environment.

When you create the new forest, the server is rebooted, and the only account active on the server is the TREYRESEARCH\Administrator account, which has the same password as the safe mode password you used with Install-ADDSForest.

To find out what Forest Mode, Domain Mode, and Schema Version you’ve just created, use the following.

Get the current Schema version and Forest and Domain Modes 
The Get-myADVersion script queries the AD to discover the current AD schema version,
and the forest mode and domain mode. If run without parameters, it will query the  
current AD context, or if a Domain Controller is specified, it will query against  
that DC’s context. Must be run as a user with sufficient privileges to query AD DS.  
Queries against the current AD context.  
Get-myADVersion -DomainController Trey-DC-02 
Gets the AD versions for the Domain Controller “Trey-DC-02” 
.Parameter DomainController 
Specifies the domain controller to query. This will change the response to match  
the AD context of the DC.  
    Author: Charlie Russel 
 Copyright: 2015 by Charlie Russel 
          : Permission to use is granted but attribution is appreciated 
   Initial: 3/7/2015 (cpr) 
if ($DomainController) {  
   $AD = Get-ADRootDSE -Server $DomainController 
   Get-ADObject $AD.SchemaNamingContext -Server $DomainController ` 
                                        -Property ObjectVersion 
} else { 
   $AD = Get-ADRootDSE 
   Get-ADObject $AD.SchemaNamingContext -Property ObjectVersion 
$Forest = $AD.ForestFunctionality 
$Domain = $AD.DomainFunctionality 
# Use a Here-String to print out the result. 
$VersionCodes = @” 
Forest: $Forest 
Domain: $Domain 
Where the Schema version is: 
72 = Windows Server Technical Preview Build 9841 
69 = Windows Server 2012 R2 
56 = Windows Server 2012 
47 = Windows Server 2008 R2 
44 = Windows Server 2008 
31 = Windows Server 2003 R2 
30 = Windows Server 2003 
13 = Windows 2000 

The result of running Get-myADVersion is shown in Figure 1-2.

Figure 1-2

Figure 1-2 Results showing that the schema version for Preview Build 9841 is 72

Install-ADDSForest has some additional options that might be useful in your environment and that allow you to tweak the initial configuration. Table 1-2 shows a fuller list of the options for Install-ADDSForest.

Table 1-2 Key parameters for Install-ADDSForest






The fully qualified domain name of the new domain ( in this book’s example).



Attempts to create a DNS delegation to the new DNS server.

[-DatabasePath ]


The location to store the domain database. Must be a localfixed disk.

[-DnsDelegationCredential ]


A credential object with permission to create the DNSdelegation.

[-DomainMode ]


The AD DS domain functional level of the new domain.

[-DomainNetbiosName ]


The NetBIOS name of the new domain (TREYRESEARCH in thisbook’s example).

[-ForestMode ]


The AD DS forest functional level of the new forest.



Suppresses confirmation prompts.



Installs Active Directory Integrated DNS server. Defaultvalue is calculated based on the environment.

[-LogPath ]


Path to the log of the install.



Specifies that there are no DNS servers present on thenetwork. Active Directory Integrated DNS is installed, and the networkadapter or adapters are configured to use and ::1 as the DNSserver.



Prevents the server from rebooting after the installation completes. Fair warning—the server is in an interim state and is not stable. Using this switch is really a bad idea.

[-SafeModeAdministratorPassword ]


Sets the DSRM password. If it is not specified, the user is prompted for the password and a confirming password.



Skips automatic configuration of DNS settings. Used if the DNS Server service is already installed.



Doesn’t test the environment to find out whether the installation will succeed. Only recommended when you’re separately running Test-ADDSForestInstallation.

[-SysvolPath ]


Fully qualified local path to the fixed disk where the SYSVOL file is written.