Deploy Active Directory with PowerShell DSC (a.k.a. “DSC-PROMO”)

Active Directory and PowerShell DSC

Today’s post is the first in a series on using PowerShell DSC with Active Directory. I don’t know how many blog posts there will be. I haven’t written them yet. What I can tell you, is that I have a load of fun scripts to share. Today we will start out with deploying a new forest using PowerShell DSC.

What is PowerShell DSC?

First things first. I highly encourage you to go watch the two days of free DSC training over at Microsoft Virtual Academy:

Jeffrey Snover and Jason Helmick did a fantastic job with these videos. The hand puppets were kinda creepy, but the rest of it is exceptional.

The Setup Part

OK. You want to spin up an AD lab, but you don’t want to baby sit the process… click next… click next… retype the password… click next…. We’ve all been there. PowerShell DSC is your shortcut. Here is what you need to get started:

  • A Windows Server 2012 R2 machine, VM, Azure VM, etc. all patched up and ready to go
  • The xActiveDirectory resource module downloaded from TechNet Script Center
  • A large tub of tapioca pudding

The pudding is optional. But who doesn’t like pudding?! If you are running PowerShell v5, then you can use “Install-Module xActiveDirectory” to grab the resource module. Put it under C:\Program Files\WindowsPowerShell\Modules\.

For the grand finale paste the code below into your ISE and press F5. Done! That’s it. Really. You’re done. Just watch the pretty blue stuff scroll by, you’ll get a reboot, and now your new test forest is ready.

The DSC Part

You will notice on the xActiveDirectory download page there is some sample code at the bottom. I used copy and paste like a boss! Then I added some of my own tweaks that will help you.

configuration NewDomain             
    Import-DscResource -ModuleName xActiveDirectory             
    Node $AllNodes.Where{$_.Role -eq "Primary DC"}.Nodename             
            ActionAfterReboot = 'ContinueConfiguration'            
            ConfigurationMode = 'ApplyOnly'            
            RebootNodeIfNeeded = $true            
        File ADFiles            
            DestinationPath = 'N:\NTDS'            
            Type = 'Directory'            
            Ensure = 'Present'            
        WindowsFeature ADDSInstall             
            Ensure = "Present"             
            Name = "AD-Domain-Services"             
        # Optional GUI tools            
        WindowsFeature ADDSTools            
            Ensure = "Present"             
            Name = "RSAT-ADDS"             
        # No slash at end of folder paths            
        xADDomain FirstDS             
            DomainName = $Node.DomainName             
            DomainAdministratorCredential = $domainCred             
            SafemodeAdministratorPassword = $safemodeAdministratorCred            
            DatabasePath = 'N:\NTDS'            
            LogPath = 'N:\NTDS'            
            DependsOn = "[WindowsFeature]ADDSInstall","[File]ADFiles"            
# Configuration Data for AD              
$ConfigData = @{             
    AllNodes = @(             
            Nodename = "localhost"             
            Role = "Primary DC"             
            DomainName = ""             
            RetryCount = 20              
            RetryIntervalSec = 30            
            PsDscAllowPlainTextPassword = $true            
NewDomain -ConfigurationData $ConfigData `
    -safemodeAdministratorCred (Get-Credential -UserName '(Password Only)' `
        -Message "New Domain Safe Mode Administrator Password") `
    -domainCred (Get-Credential -UserName alpineskihouse\administrator `
        -Message "New Domain Admin Credential")            
# Make sure that LCM is set to continue configuration after reboot            
Set-DSCLocalConfigurationManager -Path .\NewDomain –Verbose            
# Build the domain            
Start-DscConfiguration -Wait -Force -Path .\NewDomain -Verbose            

Let's talk tweaks.

Tweak #1: LocalConfigurationManager

I am running KB3000850 in my lab, as you should, too. This rollup from November 2014 fixes a bunch of DSC issues and improves the DSC experience significantly for PowerShell v4. Try it; you'll like it! This update adds the Local Configuration Manager (LCM) option ActionAfterReboot.

  • ActionAfterReboot = 'ContinueConfiguration'
    Makes sure to continue configuring after the reboot. AD DCs require a reboot in the process, and we want to make sure we keep rolling after that reboot. This will be more important later in the series after we build on top of this configuration.
  • ConfigurationMode = 'ApplyOnly'
    I chose ApplyOnly, because ApplyAndAutoCorrect is overkill for what I need.
  • RebootNodeIfNeeded = $true
    This allows the server to automatically reboot as necessary during the configuration process. It may not be agreeable in production, but in the lab it is fine.

With this LCM baseline we are ready to start configuring the DC.

Tweak #2: AD Files Path

Domain controllers really don’t like disk write-caching. Not good for the database files in some cases. Because I am building my DC on an Azure VM I have provisioning a no-write-caching disk to hold the database and logs, and I have given it the letter N: (for NTDS). My configuration creates the folder where the files will go.

Tweak #3: GUI Tools

Ssshhhh. Don’t tell anyone. I’m a PowerShell guy through-and-through, but sometimes I have a weak moment and use the GUI. In my lab I want AD Administrative Center for convenience, but I would probably skip it on a production DC. This does not come with the default install, so I added the feature: RSAT-ADDS.

Tweak #4: Path Parameters

I’ve already created the N:\NTDS path earlier in the configuration. Now I have to pass that path into the xADDomain resource for database and log parameters. These parameters were a recent and welcome update to the resource! Note that the install will fail if this path does not already exist. That’s why we put it in the configuration above.

Tweak #5: Domain Name

Are you tired of seeing in all our demos? So am I. I chose Doesn’t that sound more fun? That is actually a lesser-used-Microsoft-legal-approved demo domain we have. Change it to whatever you like.

Let ‘er rip, tater chip!

Save your tweaked script, cross your fingers, and press F5 in the ISE. You will get two credential prompts:

  1. Safe mode password
    Just the password. Nothing more. Used for AD recovery.
  2. Domain administrator credential
    From the documentation: “Credentials used to query for domain existence. Note: These are not used during domain creation.” When DSC does the test to see if the domain exists already it will need these credentials.

The blue verbose scroll is my favorite part of playing with PowerShell DSC. Be warned, however. It will come to an abrupt halt and reboot the server at the end. Feel free to take screen captures to show the family later.

How is this easier?

You might be thinking, “Wait a minute. I could have done this with a single cmdlet: Install-ADDSForest. Why go to all this trouble?” I’m glad you asked. Later in the series we are going to build more automation on top of this. In the end you will have a complete lab. Hang in there.

Lesson 1 Done

There you go. You have deployed an Active Directory forest with PowerShell Desired State Configuration (DSC). Now you have a simple configuration to use any time you want to build a clean AD lab. Later in this series we will look at configuring the new forest and then adding data like users and organizational units. Stay tuned!

Comments (15)

  1. jrv says:

    Nice start. I like that many are posting about DSC. It will become an invaluable tool.

  2. anonymouscommenter says:

    Cool. Just checking though, I need Powershell v5 for this?

  3. anonymouscommenter says:

    I’ll read the article and info on the DSC resource kit page properly before asking questions 🙂 Looks like Powershell v4 is the minimum version needed..

    Looking forward to the next article on this..

  4. You’ll need Windows Server 2012 or above, with WMF 4.0 or above.

  5. anonymouscommenter says:

    Great Article !
    Thanks !

  6. anonymouscommenter says:

    Great stuff. When’s the next post on this? 😉

  7. anonymouscommenter says:

    Today’s post is the second in a series on using PowerShell DSC with Active Directory . We will demonstrate configuring the AD Recycle Bin and domain trusts with PowerShell Desired State Configuration. As a bonus we will throw in a registry key for

  8. MSBen says:


    I have been trying to enforce
    PSDscAllowPlainTextPassword = $false
    PSDscAllowDomainUser = $true
    Although I can’t figure out to implement this.

    Any ideas?

    1. Emmanuel Paré says:

      You can add this at the bottom

      $cd = @{
      AllNodes = @(
      NodeName = ‘localhost’
      PSDscAllowPlainTextPassword = $true
      Then call with the following Parameter -ConfigurationData $cd

  9. Oliver says:

    I have been trying for a couple of days to get this all to work seamlessly through ARM templates, and I am to the point where I can get simple DSC stuff like deploying a file to work, however, with the xActiveDirectory stuff I am stumped on how to get DCPromo to actually happen. I have a local VM spun up to test DSC before I try deploying with an ARM template, but for the life of me I can’t get DCPromo to just happen on its own. Is it assumed in here that you are running DCPromo manually? Or for you does this work?

  10. Lars Panzerbjørn says:

    Were there any more posts in this series?

  11. Panzerbjrn says:

    Were there any more posts in this series?

    1. I couldn’t find any ARM template examples in the blog series so far.

  12. Anmol Ganju says:

    A command that prompts the user failed because the host program or the command type does not support user interaction. The host was attempting to request confirmation with the following message: New Domain Safe Mode Administrator Password (A command that prompts the user failed because the host program or the command type does not support user interaction. The host was attempting to request confirmation with the following message: New Domain Safe Mode Administrator Password)

Skip to main content