Set Up Active Directory on AWS EC2

Deploy a Domain Controller on EC2 and join a client machine to your domain.

Introduction

30 Second Summary

Every time you log into a work computer or access a company resource, something behind the scenes is checking who you are and what you're allowed to do. At most large organizations, that something is Active Directory.

In this project, you will turn an AWS EC2 instance into an Active Directory Domain Controller, build an organizational structure with departments and users, and prove it all works by joining a second machine to your domain.

What You'll Build

When you finish, you can log into a separate Windows machine using domain credentials you created, and your Domain Controller decides who gets in and who doesn't.

By the end of this project, you'll have:

  • Your EC2 instance transformed into an Active Directory Domain Controller with integrated DNS that manages authentication for your entire domain.
  • A real enterprise-style organizational structure with departments, user accounts, and security groups that you manage from a centralized console.
  • A second EC2 instance successfully joined to your domain, proving end-to-end domain authentication works with credentials you control.
  • Secret Mission: Enforce a Group Policy on domain-joined machines and automate bulk user creation with PowerShell.

Are there any prerequisites?

You need an AWS account with a running EC2 Windows Server instance (t3.large recommended) that you can access via RDP. If you don't have one yet, launch a Windows Server instance from the EC2 console before starting this project.

Before We Start

Before We Start...

Before we dive in, let's lock in what you're about to build and why it matters.

Prepare Your Server for Active Directory

Your EC2 instance is currently a generic Windows Server with a randomly assigned hostname and default DNS settings. Before it can become a Domain Controller, it needs two things: a meaningful hostname that identifies it as a DC, and a DNS configuration that points to itself.

Active Directory is completely dependent on DNS to function. Every domain-joined machine uses DNS to locate the Domain Controller. If DNS is not configured correctly, nothing else in AD works.

In this step, get ready to:
  • Rename your server to DC01 and reboot.
  • Configure DNS to point to the server itself and open AD ports in the security group.
  • Verify the hostname and DNS changes took effect.
Rename your server to DC01

Domain Controllers in enterprise environments follow naming conventions so administrators can identify them at a glance. You will rename your server to DC01 to signal its role as your first Domain Controller.

  • In your RDP session, right-click the Start button and select Windows PowerShell (Admin) or Terminal (Admin).
  • Rename your server and trigger a reboot by running this command:
Rename-Computer -NewName "DC01" -Restart

What does this command do?

Rename-Computer changes the Windows computer name from its current auto-generated name to DC01.

The -Restart flag forces an immediate reboot because Windows requires a restart for hostname changes to take effect.

Your RDP session will disconnect when the server reboots.

  • Wait about 1-2 minutes for the instance to finish restarting.
  • Reconnect to the instance via RDP using the same public IP address and credentials as before.

Can't reconnect via RDP?

Give the instance a full 2 minutes to reboot. If you still cannot connect, check the EC2 console to confirm the instance state shows Running.

Also confirm your security group still allows inbound RDP (TCP port 3389) from your IP address.

Help me reconnect to my EC2 instance via RDP after a reboot.

  • Once reconnected, open PowerShell as Administrator again by right-clicking Start and selecting Windows PowerShell (Admin) or Terminal (Admin).
  • Confirm the rename worked by running:
hostname

You should see DC01 returned in the output.

Configure DNS and open AD ports in the security group

Right now your server's network adapter uses Amazon's default VPC DNS resolver. That resolver has no knowledge of your future AD domain. You need to point DNS to the server itself (127.0.0.1) so that once AD is installed, the server can resolve its own domain records.

  • In your PowerShell window, first identify your network adapter's interface index by running:
Get-NetAdapter

You will see an adapter listed (typically named Ethernet or similar) with a numeric ifIndex value.

  • Set the preferred DNS server to 127.0.0.1 by running this command:
Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses ("127.0.0.1")

What does this command do?

Set-DnsClientServerAddress statically assigns DNS server addresses to a network interface, overriding DHCP-provided settings.

By setting the address to 127.0.0.1 (the loopback address), you are telling this server to ask itself for DNS lookups. Once AD DS and DNS are installed in the next step, this server will answer those queries with its own AD-integrated DNS zone.

Getting an error about the interface alias?

Your adapter might have a different name than Ethernet. Check the exact name in the Name column from the Get-NetAdapter output and replace "Ethernet" in the command with the exact name you see.

Help me find and use the correct network adapter name on my EC2 Windows Server.

Now you need to open the firewall ports that Active Directory requires for communication between domain members and the Domain Controller.

  • Switch to your browser and open the AWS Management Console.
  • Navigate to EC2, then click Security Groups in the left sidebar under Network & Security.
  • Click on the security group attached to your Windows Server instance.
  • Click the Inbound rules tab, then click Edit inbound rules.

Add the following inbound rules, setting the Source for each to your VPC CIDR (for example, 10.0.0.0/16 or whatever your VPC uses):

  • Click Add rule. Set Type to Custom TCP, Port range to 53, Source to your VPC CIDR.
  • Click Add rule. Set Type to Custom UDP, Port range to 53, Source to your VPC CIDR.
  • Click Add rule. Set Type to Custom TCP, Port range to 88, Source to your VPC CIDR.
  • Click Add rule. Set Type to Custom UDP, Port range to 88, Source to your VPC CIDR.
  • Click Add rule. Set Type to Custom TCP, Port range to 135, Source to your VPC CIDR.
  • Click Add rule. Set Type to Custom TCP, Port range to 389, Source to your VPC CIDR.
  • Click Add rule. Set Type to Custom UDP, Port range to 389, Source to your VPC CIDR.
  • Click Add rule. Set Type to Custom TCP, Port range to 445, Source to your VPC CIDR.
  • Click Add rule. Set Type to Custom TCP, Port range to 636, Source to your VPC CIDR.
  • Click Add rule. Set Type to Custom TCP, Port range to 3389, Source to your VPC CIDR.
  • Click Add rule. Set Type to Custom TCP, Port range to 49152-65535, Source to your VPC CIDR.
  • Click Save rules.

Why so many ports?

Active Directory uses multiple protocols to handle different aspects of domain communication. Port 53 is for DNS queries. Port 88 is for Kerberos authentication. Port 135 is the RPC endpoint mapper. Port 389 is LDAP. Port 445 is SMB for file replication. Port 636 is LDAPS (secure LDAP).

The range 49152-65535 covers dynamic RPC high ports that Windows uses for AD replication and Group Policy distribution.

Find your VPC CIDR quickly

In the AWS Console, go to VPC and click Your VPCs. The IPv4 CIDR column shows your VPC's address range (commonly 10.0.0.0/16 or 172.31.0.0/16 for the default VPC).

Verify the hostname and DNS configuration

Before you move to the next step, confirm that both changes are in place. If either one is wrong, the AD promotion in the next step will fail.

  • Back in your RDP session's PowerShell window, run:
hostname

Before you run the next command, predict what you expect to see for the DNS Servers line.

  • Check your full network configuration by running:
ipconfig /all

In the output, look for the section that shows your Ethernet adapter. Confirm the following:

  • hostname returns DC01.
  • Under the Ethernet adapter section of ipconfig /all, the DNS Servers line shows 127.0.0.1.

DNS Servers not showing 127.0.0.1?

If you still see an Amazon DNS address (like 10.0.0.2), the Set-DnsClientServerAddress command may have targeted the wrong interface. Run Get-NetAdapter again and confirm the adapter name matches what you used in the command.

Help me fix my DNS configuration on my EC2 Windows Server so it points to 127.0.0.1.

Your server is now named DC01, its DNS points to itself, and the security group allows AD traffic within the VPC. Next up, you will install Active Directory Domain Services and promote this machine into a full Domain Controller.

Install AD DS and Promote to Domain Controller

In the previous step, you prepared DC01 with a proper hostname and DNS configuration. Now it's time for the big transformation.

Right now, DC01 is just a regular Windows Server. In this step, you will install the Active Directory Domain Services role and promote the server to a Domain Controller. After promotion, every authentication decision in your domain flows through this machine.

In this step, get ready to:
  • Install the AD DS role and management tools using PowerShell.
  • Promote DC01 to a Domain Controller by creating a new Active Directory forest.
  • Verify the promotion succeeded after the automatic reboot.
Install the AD DS role and management tools

Before your server can become a Domain Controller, it needs the Active Directory Domain Services software role installed. This adds the binaries and tools that make domain promotion possible.

  • In your RDP session on DC01, open PowerShell (it should already be open from the previous step).
  • Install the AD DS role and its management tools by running this command:
Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools

This takes a minute or two to complete. You should see a table with Success in the output and True under the Restart Needed column (no reboot required yet).

What does this command do?

Install-WindowsFeature adds Windows Server roles and features. The -Name AD-Domain-Services parameter specifies the Active Directory role. The -IncludeManagementTools flag also installs GUI tools like Active Directory Users and Computers, which you will use in later steps.

Without -IncludeManagementTools, PowerShell only installs the role itself with no management interface.

Seeing an access denied error?

Make sure you are running PowerShell as Administrator. Right-click the PowerShell icon in the taskbar and select Run as Administrator.

help me fix an access denied error when running Install-WindowsFeature on Windows Server

Promote the server to a Domain Controller

With the AD DS role installed, you can now promote DC01 to the first Domain Controller in a brand new forest. A forest is the top-level container in Active Directory. Creating one establishes your domain from scratch.

  • Promote DC01 to a Domain Controller by running this command:
Install-ADDSForest -DomainName "corp.mylab.local" -DomainNetbiosName "CORP" -InstallDns:$true -Force:$true

What does this command do?

  • -DomainName "corp.mylab.local" sets the fully qualified domain name for your new Active Directory domain.
  • -DomainNetbiosName "CORP" sets the short name used in logins like CORP\Administrator.
  • -InstallDns:$true installs and configures a DNS server integrated with Active Directory. AD cannot function without DNS.
  • -Force:$true suppresses confirmation prompts so the promotion proceeds without extra clicks.

You will be prompted for a password

After you press Enter, PowerShell will ask you to set a SafeModeAdministratorPassword (also called the DSRM password). This is a recovery password used only if you need to start the server in Directory Services Restore Mode.

  • Type a strong password (at least 8 characters, with uppercase, lowercase, and a number).
  • Type it again to confirm.
  • Remember this password. You will not need it for normal operations, but it is your emergency recovery key.

The characters will not appear on screen as you type. This is normal security behavior.

After you enter the DSRM password, the promotion process begins. You will see progress messages as Active Directory configures the forest, creates the domain, and sets up DNS zones. The server will automatically reboot when finished.

Why does the server reboot automatically?

Promoting a server to a Domain Controller fundamentally changes how it handles authentication and network services. The reboot finalizes these changes and starts the AD DS services fresh.

Your RDP session will disconnect during this reboot. This is expected. Wait about 2-3 minutes before reconnecting.

Promotion seems stuck or RDP disconnected immediately?

The promotion process takes 3-5 minutes. If your RDP session disconnects, that means the reboot has started. Wait 2-3 minutes, then reconnect using the same RDP connection details.

help me troubleshoot an AD DS forest promotion that seems stuck or disconnected

Reconnect and verify the promotion

After the automatic reboot, your server is now a Domain Controller. Time to reconnect and confirm everything worked.

  • Wait 2-3 minutes for the reboot to complete.
  • Reconnect to DC01 via RDP using the same connection details as before.
  • On the login screen, notice that the username now shows CORP\Administrator instead of just Administrator. This confirms the server is now part of the CORP domain.
  • Log in with your existing Administrator password.

Before you run the next command, what do you think Get-ADDomain will show if the promotion succeeded?

  • Open PowerShell and verify the domain is active by running:
Get-ADDomain

You should see output confirming the domain name is corp.mylab.local and the NetBIOS name is CORP. Your server is now the authoritative Domain Controller for this forest.

Get-ADDomain returns an error?

If you see a message about the server not being operational, the AD DS services may still be starting. Wait another minute and try again.

If the command is not recognized, the promotion may not have completed. Check the Event Viewer under Windows Logs > System for any errors related to the directory service.

help me troubleshoot Get-ADDomain not working after promoting my server to a Domain Controller

Your server has officially transformed into a Domain Controller. Next up, you will build an organizational structure with departments, users, and security groups to mirror a real enterprise.

Build Your Organization

Your Domain Controller is online and managing authentication for corp.mylab.local. But right now there is nothing to authenticate against.

A Domain Controller without an organizational structure is like a filing cabinet with no folders. You need Organizational Units, user accounts, and security groups to mirror how a real company manages access. This is exactly what cloud engineers configure when onboarding enterprises to Active Directory.

In this step, get ready to:
  • Create Organizational Units for three departments.
  • Create user accounts with department-specific attributes.
  • Create security groups and assign users to them.
Create Organizational Units for your departments

Organizational Units (OUs) are containers inside Active Directory that group objects like users, computers, and groups by department, location, or function. They also serve as targets for Group Policy later.

  • In your PowerShell window on DC01, create three OUs by running these commands:
# Create an OU for each department
New-ADOrganizationalUnit -Name "Engineering" -Path "DC=corp,DC=mylab,DC=local"
New-ADOrganizationalUnit -Name "Finance" -Path "DC=corp,DC=mylab,DC=local"
New-ADOrganizationalUnit -Name "HR" -Path "DC=corp,DC=mylab,DC=local"

What does this code do?

Each New-ADOrganizationalUnit command creates a folder-like container in your domain's directory tree. The -Name parameter sets the OU's display name. The -Path parameter tells Active Directory where to place the OU, using the domain's distinguished name format.

  • Confirm the OUs were created by running:
Get-ADOrganizationalUnit -Filter * | Select-Object Name, DistinguishedName

You should see Engineering, Finance, and HR listed with their full paths under DC=corp,DC=mylab,DC=local.

Not seeing your OUs?

  • Check for typos in the -Path value. It must be exactly DC=corp,DC=mylab,DC=local with no spaces after the commas.
  • If you see a "directory object not found" error, confirm your domain promotion completed successfully by running Get-ADDomain.
  • help me troubleshoot why my Organizational Units weren't created in Active Directory
Create user accounts in each department

Each OU needs users. You will create two accounts per department with realistic attributes like job title and department name. These are the accounts people would log in with on domain-joined machines.

  • Create the Engineering department users by running:
# Create users in the Engineering OU
New-ADUser -Name "John Smith" -SamAccountName "jsmith" -UserPrincipalName "jsmith@corp.mylab.local" -Path "OU=Engineering,DC=corp,DC=mylab,DC=local" -Department "Engineering" -Title "Software Engineer" -AccountPassword (ConvertTo-SecureString "P@ssw0rd123" -AsPlainText -Force) -Enabled $true

New-ADUser -Name "Patricia Jones" -SamAccountName "pjones" -UserPrincipalName "pjones@corp.mylab.local" -Path "OU=Engineering,DC=corp,DC=mylab,DC=local" -Department "Engineering" -Title "DevOps Engineer" -AccountPassword (ConvertTo-SecureString "P@ssw0rd123" -AsPlainText -Force) -Enabled $true

What do these parameters do?

  • -SamAccountName is the short login name (e.g. CORP\jsmith).
  • -UserPrincipalName is the email-style login (e.g. jsmith@corp.mylab.local).
  • -Path places the user inside the correct OU.
  • -AccountPassword sets an initial password. ConvertTo-SecureString converts the plain text into the secure format Active Directory requires.
  • -Enabled $true activates the account immediately so users can log in.
  • Create the Finance department users by running:
# Create users in the Finance OU
New-ADUser -Name "Maria Wilson" -SamAccountName "mwilson" -UserPrincipalName "mwilson@corp.mylab.local" -Path "OU=Finance,DC=corp,DC=mylab,DC=local" -Department "Finance" -Title "Financial Analyst" -AccountPassword (ConvertTo-SecureString "P@ssw0rd123" -AsPlainText -Force) -Enabled $true

New-ADUser -Name "David Lee" -SamAccountName "dlee" -UserPrincipalName "dlee@corp.mylab.local" -Path "OU=Finance,DC=corp,DC=mylab,DC=local" -Department "Finance" -Title "Account Manager" -AccountPassword (ConvertTo-SecureString "P@ssw0rd123" -AsPlainText -Force) -Enabled $true
  • Create the HR department users by running:
# Create users in the HR OU
New-ADUser -Name "Tina Chen" -SamAccountName "tchen" -UserPrincipalName "tchen@corp.mylab.local" -Path "OU=HR,DC=corp,DC=mylab,DC=local" -Department "HR" -Title "HR Coordinator" -AccountPassword (ConvertTo-SecureString "P@ssw0rd123" -AsPlainText -Force) -Enabled $true

New-ADUser -Name "Robert Brown" -SamAccountName "rbrown" -UserPrincipalName "rbrown@corp.mylab.local" -Path "OU=HR,DC=corp,DC=mylab,DC=local" -Department "HR" -Title "Recruiter" -AccountPassword (ConvertTo-SecureString "P@ssw0rd123" -AsPlainText -Force) -Enabled $true
  • Verify your users were created by running:
Get-ADUser -Filter * | Select-Object Name, SamAccountName, Department

You should see all six users listed alongside the built-in accounts like Administrator and Guest. Each user shows their department assignment.

Seeing an error about password complexity?

Windows Server enforces password complexity by default. The password P@ssw0rd123 meets these requirements (uppercase, lowercase, number, special character, 8+ characters). If you changed the password in your command, make sure it includes at least three of those four categories.

help me fix a password complexity error when creating Active Directory users

Create security groups and assign members

Security groups control access to resources. When you assign a permission to a group, every member inherits that permission automatically. This is how real enterprises avoid managing permissions user by user.

  • Create a security group for each department and add users to them by running:
# Create a security group for each department
New-ADGroup -Name "Engineering Team" -GroupScope Global -GroupCategory Security -Path "OU=Engineering,DC=corp,DC=mylab,DC=local"
New-ADGroup -Name "Finance Team" -GroupScope Global -GroupCategory Security -Path "OU=Finance,DC=corp,DC=mylab,DC=local"
New-ADGroup -Name "HR Team" -GroupScope Global -GroupCategory Security -Path "OU=HR,DC=corp,DC=mylab,DC=local"

# Add users to their respective groups
Add-ADGroupMember -Identity "Engineering Team" -Members "jsmith", "pjones"
Add-ADGroupMember -Identity "Finance Team" -Members "mwilson", "dlee"
Add-ADGroupMember -Identity "HR Team" -Members "tchen", "rbrown"

What does this code do?

New-ADGroup creates a security group inside the specified OU. The -GroupScope Global setting means the group can contain members from this domain and be used for permissions anywhere in the forest.

Add-ADGroupMember links users to a group by their SAM account name. Once added, these users inherit any permissions assigned to that group.

  • Verify the group membership by running:
Get-ADGroupMember -Identity "Engineering Team" | Select-Object Name, SamAccountName

You should see John Smith and Patricia Jones listed as members of the Engineering Team group.

Group shows no members?

  • Make sure the SAM account names in your Add-ADGroupMember command match exactly what you used in New-ADUser. Run Get-ADUser -Filter * | Select-Object SamAccountName to check.
  • Verify the group exists by running Get-ADGroup -Filter * and checking that the group name matches your -Identity value exactly.
  • help me troubleshoot why Add-ADGroupMember is not adding users to my security group

Before you run the final check, what do you expect to see when you query all users and their departments?

  • Run this command to see your complete organizational structure:
Get-ADUser -Filter * | Select-Object Name, Department

You should see your six users with their departments populated (Engineering, Finance, HR). The built-in accounts like Administrator and Guest will show a blank department, which is expected.

Your domain now has a realistic organizational structure with departments, users, and access groups. Next up, you will launch a second machine and try to join it to your domain. This is where things get interesting.

Launch a Client and Attempt Domain Join

Your Domain Controller is running and your organizational structure is in place. But a Domain Controller that nothing connects to is just an expensive server sitting in a VPC.

In this step, you will launch a second EC2 instance and try to join it to your domain. The attempt will fail. This is intentional and it exposes the single most common Active Directory troubleshooting scenario in cloud environments.

In this step, get ready to:
  • Launch a t3.small Windows Server instance in the same VPC and subnet as DC01.
  • Attempt a domain join and observe the DNS-related failure.
  • Understand why Amazon's default DNS resolver cannot find your AD domain.
Launch a Windows Server client instance

You need a second machine to prove that your Domain Controller actually works. This client instance will attempt to join your domain the same way a corporate laptop would.

  • Switch to the browser tab with the AWS Management Console.
  • Navigate to the EC2 service by typing EC2 in the search bar and selecting it.
  • Click Launch instances.
  • In the Name field, enter Client.
  • Under Application and OS Images, select a Windows Server AMI (the same base version you used for DC01).
  • Under Instance type, select t3.small.
  • Under Key pair, select the same key pair you used for DC01.
  • Under Network settings, click Edit.
  • Confirm the VPC matches the same VPC your DC01 is in.
  • Confirm the Subnet matches the same subnet as DC01.
  • Under Firewall (security groups), select Select existing security group and choose the same security group you configured for DC01 (the one with AD ports open).
  • Click Launch instance.

Wait for the instance state to show Running and for the status checks to pass. This takes 2-4 minutes for a Windows instance.

  • Select the Client instance in the EC2 console.
  • Click Connect.
  • Select the RDP client tab.
  • Click Get password and decrypt using your key pair to retrieve the Administrator password.
  • Download the RDP file or copy the public DNS. Open a new RDP session to the client instance using the decrypted credentials.

Why a separate RDP session?

You now have two RDP windows open. One connects to DC01 (your Domain Controller). The other connects to the new Client instance. Keep both open throughout this step.

Attempt the domain join

With the client instance running, you can now try to join it to your corp.mylab.local domain. This is the standard process that any Windows machine uses to join a domain.

  • In the RDP session to the Client instance, right-click the Start button and select System.
  • Click Domain or workgroup (or Rename this PC (advanced) depending on your Windows Server version) to open System Properties.
  • In the System Properties window, click the Computer Name tab.
  • Click Change... next to "To rename this computer or change its domain or workgroup, click Change."
  • Under Member of, select Domain.
  • Enter corp.mylab.local in the domain field.
  • Click OK.

Before you click OK, what do you think will happen? Will the client successfully find your Domain Controller and join the domain?

After a short delay, you will see an error dialog. The domain join fails with this message:

An Active Directory Domain Controller (AD DC) for the domain corp.mylab.local could not be contacted.

This error is expected

Do not try to fix this yet. This failure is the entire point of this step. You are seeing the most common Active Directory problem in cloud environments. Click OK to dismiss the error and leave the domain join incomplete.

Understand why the domain join failed

The failure comes down to one thing: DNS. Your client instance has no idea your AD domain exists because it is asking the wrong DNS server.

  • In the client's RDP session, open PowerShell (right-click Start, select Windows PowerShell).
  • Check the client's current DNS configuration by running:
ipconfig /all

Look at the DNS Servers line in the output. You will see an IP address ending in .2 (for example, 10.0.0.2 for a 10.0.0.0/16 VPC). This is Amazon's VPC DNS resolver.

Why does Amazon's DNS resolver cause this failure?

Every EC2 instance in a VPC uses the VPC CIDR+2 address as its default DNS resolver. For a 10.0.0.0/16 VPC, that is 10.0.0.2.

This resolver handles public DNS lookups (like google.com) and AWS service endpoints. It has absolutely no knowledge of your private corp.mylab.local domain. When the client asks "where is corp.mylab.local?" the Amazon resolver answers "I have no idea" and the domain join fails.

The fix is to point the client's DNS to your Domain Controller, which hosts the DNS zone for your domain. That fix comes in the next step.

You have now seen the exact failure that cloud engineers troubleshoot constantly. Your client cannot find the Domain Controller because Amazon's default DNS knows nothing about your private AD domain. In the next step, you will fix this with a single DNS change and complete the domain join.

Fix DNS and Complete the Domain Join

In the previous step, you saw the domain join fail because the client machine had no idea your AD domain existed. The client was asking Amazon's VPC DNS resolver to find corp.mylab.local, and that resolver has no record for it.

The fix is straightforward. By pointing the client's DNS to your Domain Controller, the client can locate Active Directory services through SRV records that were automatically created when you promoted DC01. This single change unlocks domain authentication.

In this step, get ready to:
  • Change the client's DNS to point at DC01's private IP address.
  • Successfully join the client to the corp.mylab.local domain.
  • Log in as a domain user and confirm authentication works end-to-end.
Point the client's DNS to DC01

Your client machine currently asks Amazon's VPC DNS resolver for name lookups. That resolver has no knowledge of corp.mylab.local. You need to tell the client to ask DC01 instead.

  • Switch to the AWS Management Console in your browser.
  • Navigate to EC2, then click Instances.
  • Select your DC01 instance.
  • Copy the Private IPv4 address shown in the details pane. You will need this value in a moment.

Why the private IP and not the public IP?

Active Directory traffic stays inside your VPC. The private IP is the address other machines in the VPC use to reach DC01. The public IP routes through the internet gateway and is only used for your RDP connection from your local machine.

  • Switch to your RDP session on the client machine.
  • Open PowerShell as Administrator on the client.
  • Find the name of your network adapter by running this command:
Get-NetAdapter

You should see an adapter listed with a status of Up. Note the value in the Name column. On EC2 Windows instances this is typically Ethernet.

  • Set the preferred DNS server to DC01's private IP by running this command (replace the IP address with the one you copied from the EC2 console):
Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses [[DC01_PRIVATE_IP="DC01's private IPv4 address"]]

What does this command do?

  • Set-DnsClientServerAddress overrides the DHCP-provided DNS settings on the specified interface.
  • -InterfaceAlias "Ethernet" targets the network adapter you identified. If your adapter has a different name, use that name instead.
  • -ServerAddresses tells Windows to use DC01 as the DNS server. Now all name lookups from this machine go to your Domain Controller.
  • Verify the DNS change took effect by running:
Get-DnsClientServerAddress -InterfaceAlias "Ethernet" -AddressFamily IPv4

You should see DC01's private IP listed under ServerAddresses instead of the old VPC resolver address.

Still seeing the old DNS address?

  • Double-check that the interface name matches exactly what Get-NetAdapter showed you. Names are case-sensitive.
  • Make sure you ran the command in the client's PowerShell window, not on DC01.
  • help me fix my DNS client server address on my EC2 Windows instance
Retry the domain join

With DNS now pointing at DC01, the client can locate your Active Directory domain via SRV records. Time to retry the domain join that failed earlier.

  • On the client, press Win+R to open the Run dialog.
  • Type sysdm.cpl and press Enter to open System Properties.
  • Click the Computer Name tab.
  • Click Change.
  • Under Member of, select Domain.
  • Type corp.mylab.local in the domain field.
  • Click OK.

A credentials dialog appears asking who has permission to join this machine to the domain.

  • Enter CORP\Administrator as the username.
  • Enter the password you set for the Administrator account during AD DS promotion.
  • Click OK.

You should see a "Welcome to the corp.mylab.local domain" message. This confirms the domain join succeeded.

  • Click OK on the welcome message.
  • Click OK to acknowledge the restart prompt.
  • Click Close on the System Properties window.
  • Click Restart Now when prompted.

Why does a reboot happen?

When a machine joins a domain, Windows needs to establish a secure channel with the Domain Controller and update its machine account credentials. This requires a fresh boot so the computer starts with its new domain identity.

Still seeing the DNS error?

  • Run Get-DnsClientServerAddress again and confirm DC01's private IP is listed. If not, re-run the Set-DnsClientServerAddress command.
  • Confirm your security group allows traffic from the client to DC01 on the required AD ports (TCP/UDP 53, 88, 135, 389, 445, 636, 49152-65535).
  • Test connectivity by running nslookup corp.mylab.local on the client. If it resolves, DNS is working and the issue is elsewhere.
  • help me troubleshoot my Active Directory domain join failure on EC2
Log in as a domain user and verify

The real proof that Active Directory works is logging in as one of the domain users you created earlier. The client machine has never seen this user before. It has to authenticate against DC01.

  • After the client reboots, reconnect via RDP.
  • On the Windows login screen, click Other user.
  • Enter a domain username you created in Step 3 (for example, CORP\jsmith).
  • Enter the password you set for that user.
  • Press Enter to log in.

Windows will say "Preparing your desktop" as it creates a profile for this domain user on the client for the first time.

  • Once the desktop loads, open a command prompt or PowerShell window.

Before you run the next command, what do you expect whoami to return? Think about whether this machine is now aware of domain accounts.

  • Run this command to confirm your identity:
whoami

You should see corp\jsmith (or whichever domain user you logged in as). This proves the client authenticated against your Domain Controller.

  • Now confirm the computer's domain membership by running:
gpresult /r

In the output, look for the COMPUTER SETTINGS section. You should see entries referencing corp.mylab.local under the site and domain information. This confirms the machine is a domain member and receiving policy from your Domain Controller.

What does gpresult /r show?

The gpresult /r command displays the Resultant Set of Policy summary for the computer and user. It shows which domain the machine belongs to, which OU it sits in, and which Group Policy Objects are applied. This is the standard verification tool for domain membership and policy application.

Seeing access denied when running gpresult?

  • Run the command prompt as Administrator. Right-click the Command Prompt or PowerShell icon and select Run as administrator.
  • If logged in as a standard domain user, you may only see user settings. The computer settings section requires elevated privileges.
  • help me run gpresult on my domain-joined Windows client

You just solved the most common Active Directory issue in cloud environments. A one-line DNS change was all that stood between a failed domain join and full domain authentication. Next up, put your skills to the test with the Secret Mission.

Secret mission

Group Policy and PowerShell Automation

Real cloud engineers do not create users one at a time. They enforce policies at scale and automate repetitive tasks. In this secret mission, you will create a Group Policy Object that visibly changes domain-joined machines, then write a PowerShell script that bulk-creates 10 users from a CSV file into the correct OUs.

Clean Up Your Resources

Clean Up Your Resources

Decide whether to keep your resources running, pause them to come back later, or delete them entirely. This project uses paid EC2 instances that accrue charges every hour they run.

Cost warning

Your DC01 instance (t3.large) costs approximately $0.12/hr and your client instance (t3.small) costs approximately $0.03/hr, both including Windows licensing. If you leave both running overnight (8 hours), that is roughly $1.20 in charges.

If you are done experimenting, stop or terminate both instances to avoid unexpected charges on your AWS bill.

Resources you used:

  • EC2 t3.large instance (DC01) running as your Domain Controller.
  • EC2 t3.small instance (client) joined to your domain.
  • Security group with Active Directory ports open within your VPC.

Keep everything running

No action needed. Choose this if you are still actively experimenting with Active Directory, Group Policy, or PowerShell automation.

  • Both EC2 instances will continue running and accruing hourly charges (~$0.15/hr combined).
  • Your domain, users, OUs, GPOs, and security groups remain intact and accessible via RDP.
  • Check the AWS Billing Dashboard periodically to monitor costs.

Pause - I'll come back to this later

Stop both instances to eliminate compute charges while keeping your EBS volumes and configuration intact. You can start them again later and pick up where you left off.

  • In the AWS Console, navigate to EC2 then Instances.
  • Select your DC01 instance (t3.large).
  • Click Instance state then Stop instance.
  • Repeat for your client instance (t3.small).
  • EBS storage charges still apply at approximately $0.08/GB/month while instances are stopped.

Delete - I don't want to use this again

Terminate both instances and delete all associated resources to return your AWS bill to $0 for this project.

  • In the AWS Console, navigate to EC2 then Instances.
  • Select your client instance (t3.small).
  • Click Instance state then Terminate instance. Confirm when prompted.
  • Select your DC01 instance (t3.large).
  • Click Instance state then Terminate instance. Confirm when prompted.
  • Terminating an instance automatically deletes its attached EBS volume if Delete on termination was enabled (the default for root volumes).
  • Navigate to EC2 then Volumes. If any volumes from these instances still show as available, select them, click Actions then Delete volume.
  • Navigate to EC2 then Security Groups. Select the security group you created for Active Directory ports.
  • Click Actions then Delete security groups. Confirm when prompted.

When can I delete the security group?

You can only delete a security group after all instances using it have been terminated. If you see an error, wait a minute for the instances to fully terminate and try again.

Nice Work!

Nice Work!

You just built a fully functional Active Directory environment on AWS from scratch. Your EC2 instance is now a Domain Controller managing authentication for an entire domain, complete with organizational structure and a joined client machine proving it all works end to end.

Here's what you learned:

  • Promoted a Windows Server EC2 instance to an Active Directory Domain Controller with integrated DNS.
  • Built an enterprise-style organizational structure with Organizational Units, user accounts, and security groups.
  • Diagnosed and resolved the most common AD-in-cloud issue: DNS misconfiguration preventing domain joins.
  • Successfully joined a client machine to the domain and authenticated with domain credentials.
  • Secret Mission: Enforced Group Policy across domain machines and automated bulk user provisioning with PowerShell.

Ready to quiz yourself?