Skip to content

Project 2: Hybrid Identity with Azure AD ​

Overview ​

Implement a hybrid identity solution that synchronizes on-premises Active Directory with Microsoft Entra ID (Azure AD). This project simulates enterprise identity management with SSO, MFA, Conditional Access, and Privileged Identity Management.

Difficulty: Advanced
Duration: 6-8 hours
Cost: ~$30-50/month (VMs for AD DS)

Architecture Diagram ​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                           MICROSOFT ENTRA ID (Cloud)                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚                         Tenant: contoso.onmicrosoft.com                      β”‚ β”‚
β”‚  β”‚                                                                              β”‚ β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
β”‚  β”‚  β”‚  Users &     β”‚  β”‚  Conditional β”‚  β”‚  MFA &       β”‚  β”‚  Enterprise      β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  Groups      β”‚  β”‚  Access      β”‚  β”‚  SSPR        β”‚  β”‚  Applications    β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  (synced)    β”‚  β”‚  Policies    β”‚  β”‚              β”‚  β”‚  (SSO enabled)   β”‚ β”‚ β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
β”‚  β”‚                                                                              β”‚ β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
β”‚  β”‚  β”‚  PIM         β”‚  β”‚  Identity    β”‚  β”‚  Access      β”‚  β”‚  App             β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  (JIT Admin) β”‚  β”‚  Protection  β”‚  β”‚  Reviews     β”‚  β”‚  Registrations   β”‚ β”‚ β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                        β”‚
                                        β”‚ Azure AD Connect
                                        β”‚ (Password Hash Sync)
                                        β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                              AZURE INFRASTRUCTURE                                β”‚
β”‚                                                                                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚
β”‚  β”‚                    VNet: vnet-identity (10.10.0.0/16)                        β”‚β”‚
β”‚  β”‚                                                                              β”‚β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚β”‚
β”‚  β”‚  β”‚  Subnet: snet-addc             β”‚  β”‚  Subnet: snet-aadconnect            β”‚β”‚β”‚
β”‚  β”‚  β”‚  (10.10.1.0/24)                β”‚  β”‚  (10.10.2.0/24)                     β”‚β”‚β”‚
β”‚  β”‚  β”‚                                β”‚  β”‚                                     β”‚β”‚β”‚
β”‚  β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚β”‚β”‚
β”‚  β”‚  β”‚  β”‚  vm-dc01                 β”‚  β”‚  β”‚  β”‚  vm-aadconnect              β”‚   β”‚β”‚β”‚
β”‚  β”‚  β”‚  β”‚  Windows Server 2022    β”‚  β”‚  β”‚  β”‚  Windows Server 2022        β”‚   β”‚β”‚β”‚
β”‚  β”‚  β”‚  β”‚                         β”‚  β”‚  β”‚  β”‚                             β”‚   β”‚β”‚β”‚
β”‚  β”‚  β”‚  β”‚  Roles:                 β”‚  β”‚  β”‚  β”‚  Components:                β”‚   β”‚β”‚β”‚
β”‚  β”‚  β”‚  β”‚  - AD DS                β”‚  β”‚  β”‚  β”‚  - Azure AD Connect         β”‚   β”‚β”‚β”‚
β”‚  β”‚  β”‚  β”‚  - DNS                  β”‚  β”‚  β”‚  β”‚  - Health Agent             β”‚   β”‚β”‚β”‚
β”‚  β”‚  β”‚  β”‚                         β”‚  β”‚  β”‚  β”‚                             β”‚   β”‚β”‚β”‚
β”‚  β”‚  β”‚  β”‚  Domain:                β”‚  β”‚  β”‚  β”‚  Sync Mode:                 β”‚   β”‚β”‚β”‚
β”‚  β”‚  β”‚  β”‚  contoso.local          │──┼──┼──│  Password Hash Sync         β”‚   β”‚β”‚β”‚
β”‚  β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚β”‚β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚
β”‚                                                                                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚
β”‚  β”‚                         Azure Bastion (Secure Access)                        β”‚β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Identity Flow:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ On-Prem   │───▢│  Azure AD │───▢│ Conditional│───▢│  Cloud Apps   β”‚
β”‚ User Loginβ”‚    β”‚  Connect  β”‚    β”‚   Access   β”‚    β”‚  (SSO)        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

What You'll Learn ​

  • Deploy Active Directory Domain Services in Azure
  • Install and configure Azure AD Connect
  • Configure Password Hash Sync
  • Set up Multi-Factor Authentication (MFA)
  • Create Conditional Access policies
  • Implement Self-Service Password Reset (SSPR)
  • Configure Privileged Identity Management (PIM)
  • Set up Access Reviews

Prerequisites ​

  • Azure subscription with Global Administrator access
  • Azure AD Premium P2 license (trial available)
  • Basic understanding of Active Directory

Phase 1: Create Azure Infrastructure ​

Step 1.1: Create Resource Group and VNet ​

bash
# Set variables
LOCATION="eastus"
RG_NAME="rg-identity-lab-eastus"
DOMAIN_NAME="contoso.local"
ADMIN_USER="domainadmin"
ADMIN_PASSWORD="P@ssw0rd123!Complex"

# Create resource group
az group create \
  --name $RG_NAME \
  --location $LOCATION \
  --tags Project=HybridIdentity Environment=Lab

# Create VNet
az network vnet create \
  --resource-group $RG_NAME \
  --name vnet-identity \
  --address-prefix 10.10.0.0/16 \
  --subnet-name snet-addc \
  --subnet-prefix 10.10.1.0/24 \
  --location $LOCATION

# Add subnet for Azure AD Connect server
az network vnet subnet create \
  --resource-group $RG_NAME \
  --vnet-name vnet-identity \
  --name snet-aadconnect \
  --address-prefix 10.10.2.0/24

# Add Azure Bastion subnet
az network vnet subnet create \
  --resource-group $RG_NAME \
  --vnet-name vnet-identity \
  --name AzureBastionSubnet \
  --address-prefix 10.10.3.0/27

echo "VNet created with subnets"

Step 1.2: Create NSGs ​

bash
# Create NSG for DC subnet
az network nsg create \
  --resource-group $RG_NAME \
  --name nsg-addc \
  --location $LOCATION

# Allow RDP from Bastion only
az network nsg rule create \
  --resource-group $RG_NAME \
  --nsg-name nsg-addc \
  --name AllowRDPFromBastion \
  --priority 100 \
  --direction Inbound \
  --access Allow \
  --protocol Tcp \
  --source-address-prefixes 10.10.3.0/27 \
  --destination-port-ranges 3389

# Allow AD replication ports
az network nsg rule create \
  --resource-group $RG_NAME \
  --nsg-name nsg-addc \
  --name AllowADReplication \
  --priority 200 \
  --direction Inbound \
  --access Allow \
  --protocol "*" \
  --source-address-prefixes 10.10.0.0/16 \
  --destination-port-ranges 53 88 135 389 445 464 636 3268 3269 49152-65535

# Associate NSG with subnet
az network vnet subnet update \
  --resource-group $RG_NAME \
  --vnet-name vnet-identity \
  --name snet-addc \
  --network-security-group nsg-addc

Phase 2: Deploy Domain Controller ​

Step 2.1: Create Domain Controller VM ​

bash
# Create DC VM
az vm create \
  --resource-group $RG_NAME \
  --name vm-dc01 \
  --vnet-name vnet-identity \
  --subnet snet-addc \
  --image Win2022Datacenter \
  --size Standard_D2s_v3 \
  --admin-username $ADMIN_USER \
  --admin-password $ADMIN_PASSWORD \
  --public-ip-address "" \
  --private-ip-address 10.10.1.4

echo "DC VM created with static IP: 10.10.1.4"

Step 2.2: Configure Custom DNS for VNet ​

bash
# Set VNet DNS to DC IP
az network vnet update \
  --resource-group $RG_NAME \
  --name vnet-identity \
  --dns-servers 10.10.1.4

echo "VNet DNS configured to point to DC"

Step 2.3: Deploy Azure Bastion ​

bash
# Create Public IP for Bastion
az network public-ip create \
  --resource-group $RG_NAME \
  --name pip-bastion \
  --sku Standard \
  --allocation-method Static

# Create Azure Bastion
az network bastion create \
  --resource-group $RG_NAME \
  --name bastion-identity \
  --public-ip-address pip-bastion \
  --vnet-name vnet-identity \
  --sku Basic \
  --location $LOCATION

echo "Azure Bastion deployed"

Step 2.4: Install AD DS Role ​

Connect to vm-dc01 via Azure Bastion and run these PowerShell commands:

powershell
# Install AD DS role
Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools

# Import AD DS module
Import-Module ADDSDeployment

# Configure AD DS Forest
$SafeModePassword = ConvertTo-SecureString "P@ssw0rd123!Safe" -AsPlainText -Force

Install-ADDSForest `
  -DomainName "contoso.local" `
  -DomainNetBIOSName "CONTOSO" `
  -ForestMode "WinThreshold" `
  -DomainMode "WinThreshold" `
  -InstallDns:$true `
  -SafeModeAdministratorPassword $SafeModePassword `
  -Force:$true

# Server will restart automatically

Step 2.5: Create Test Users and Groups ​

After DC restarts, reconnect via Bastion:

powershell
# Create OUs
New-ADOrganizationalUnit -Name "Corp Users" -Path "DC=contoso,DC=local"
New-ADOrganizationalUnit -Name "Corp Groups" -Path "DC=contoso,DC=local"
New-ADOrganizationalUnit -Name "IT Admins" -Path "DC=contoso,DC=local"

# Create test users
$Password = ConvertTo-SecureString "P@ssw0rd123!" -AsPlainText -Force

# Regular users
New-ADUser -Name "John Smith" -SamAccountName "jsmith" `
  -UserPrincipalName "jsmith@contoso.local" `
  -Path "OU=Corp Users,DC=contoso,DC=local" `
  -AccountPassword $Password -Enabled $true

New-ADUser -Name "Jane Doe" -SamAccountName "jdoe" `
  -UserPrincipalName "jdoe@contoso.local" `
  -Path "OU=Corp Users,DC=contoso,DC=local" `
  -AccountPassword $Password -Enabled $true

New-ADUser -Name "Bob Wilson" -SamAccountName "bwilson" `
  -UserPrincipalName "bwilson@contoso.local" `
  -Path "OU=Corp Users,DC=contoso,DC=local" `
  -AccountPassword $Password -Enabled $true

# IT Admin users
New-ADUser -Name "Alice Admin" -SamAccountName "aadmin" `
  -UserPrincipalName "aadmin@contoso.local" `
  -Path "OU=IT Admins,DC=contoso,DC=local" `
  -AccountPassword $Password -Enabled $true

# Create groups
New-ADGroup -Name "All Employees" -GroupScope Global `
  -Path "OU=Corp Groups,DC=contoso,DC=local"

New-ADGroup -Name "IT Department" -GroupScope Global `
  -Path "OU=Corp Groups,DC=contoso,DC=local"

New-ADGroup -Name "Privileged Admins" -GroupScope Global `
  -Path "OU=Corp Groups,DC=contoso,DC=local"

# Add users to groups
Add-ADGroupMember -Identity "All Employees" -Members jsmith, jdoe, bwilson, aadmin
Add-ADGroupMember -Identity "IT Department" -Members aadmin
Add-ADGroupMember -Identity "Privileged Admins" -Members aadmin

Write-Host "Users and groups created successfully"
Get-ADUser -Filter * | Select-Object Name, SamAccountName, UserPrincipalName

Phase 3: Configure Azure AD Connect ​

Step 3.1: Create Azure AD Connect Server ​

bash
# Create AAD Connect VM
az vm create \
  --resource-group $RG_NAME \
  --name vm-aadconnect \
  --vnet-name vnet-identity \
  --subnet snet-aadconnect \
  --image Win2022Datacenter \
  --size Standard_D2s_v3 \
  --admin-username $ADMIN_USER \
  --admin-password $ADMIN_PASSWORD \
  --public-ip-address ""

echo "Azure AD Connect VM created"

Step 3.2: Join VM to Domain ​

Connect to vm-aadconnect via Bastion:

powershell
# Join domain
$DomainCred = Get-Credential  # Enter contoso\domainadmin
Add-Computer -DomainName "contoso.local" -Credential $DomainCred -Restart

Step 3.3: Prepare Azure AD ​

Before installing Azure AD Connect, configure Azure AD:

  1. Add Custom Domain (optional for production):

    • Azure Portal β†’ Microsoft Entra ID β†’ Custom domain names
    • Add your verified domain
  2. Create Sync Account (Portal):

    • Azure Portal β†’ Microsoft Entra ID β†’ Users β†’ New user
    • User name: aadconnect@contoso.onmicrosoft.com
    • Name: AAD Connect Service
    • Assign: Global Administrator role (temporarily)

Step 3.4: Install Azure AD Connect ​

Connect to vm-aadconnect via Bastion:

  1. Download Azure AD Connect:
powershell
# Download Azure AD Connect
$url = "https://www.microsoft.com/en-us/download/details.aspx?id=47594"
Start-Process $url

# Or use direct download link (check for latest version)
Invoke-WebRequest -Uri "https://download.microsoft.com/download/B/0/0/B00291D0-5A83-4DE7-86F5-980BC00DE05A/AzureADConnect.msi" -OutFile "C:\AzureADConnect.msi"

# Install
Start-Process msiexec.exe -ArgumentList '/i C:\AzureADConnect.msi /quiet' -Wait
  1. Configure Azure AD Connect (GUI):
    • Launch Azure AD Connect from Start Menu
    • Select "Customize" for more options
    • Choose: Password Hash Synchronization
    • Connect to Azure AD: Use Global Admin credentials
    • Connect to AD DS: Use contoso\domainadmin
    • Select OUs to sync:
      • βœ… OU=Corp Users
      • βœ… OU=Corp Groups
      • βœ… OU=IT Admins
    • Enable:
      • βœ… Password writeback (if P2 license)
      • βœ… Exchange hybrid deployment (optional)
    • Install and start sync

Step 3.5: Verify Synchronization ​

powershell
# On Azure AD Connect server
Import-Module ADSync

# Force sync
Start-ADSyncSyncCycle -PolicyType Delta

# Check sync status
Get-ADSyncConnectorRunStatus

# View sync errors
Get-ADSyncConnector | Get-ADSyncConnectorStatistics

In Azure Portal:

  • Navigate to Microsoft Entra ID β†’ Users
  • Verify synced users appear with "Yes" in "Directory synced" column

Phase 4: Configure Multi-Factor Authentication ​

Step 4.1: Enable Security Defaults or Conditional Access ​

Recommendation

Disable Security Defaults and use Conditional Access for granular control.

Azure Portal β†’ Microsoft Entra ID β†’ Properties β†’ Manage Security defaults β†’ No

Step 4.2: Configure Per-User MFA Settings ​

Azure Portal β†’ Microsoft Entra ID β†’ Users β†’ Per-user MFA
  • Select users (jsmith, jdoe, bwilson)
  • Click "Enable" for MFA

Step 4.3: Configure MFA Methods ​

Azure Portal β†’ Microsoft Entra ID β†’ Security β†’ Authentication methods

Enable methods:

  • βœ… Microsoft Authenticator
  • βœ… SMS
  • βœ… Email OTP
  • βœ… FIDO2 security keys

Phase 5: Configure Conditional Access ​

Step 5.1: Create Named Locations ​

Azure Portal β†’ Microsoft Entra ID β†’ Security β†’ Conditional Access β†’ Named locations

Create trusted location:

  • Name: "Corporate Office"
  • Mark as trusted location: βœ…
  • Add IP ranges: Your corporate IP ranges

Step 5.2: Create Conditional Access Policies ​

Policy 1: Require MFA for All Users

Azure Portal β†’ Microsoft Entra ID β†’ Security β†’ Conditional Access β†’ New policy
yaml
Name: Require MFA for All Users
Assignments:
  Users: All users
  Exclude: Emergency access accounts
  Cloud apps: All cloud apps
  Conditions:
    Sign-in risk: Not configured
    Device platforms: All platforms
Access controls:
  Grant: Require multi-factor authentication
Enable policy: On

Policy 2: Block Legacy Authentication

yaml
Name: Block Legacy Authentication
Assignments:
  Users: All users
  Cloud apps: All cloud apps
  Conditions:
    Client apps: 
      - Exchange ActiveSync clients
      - Other clients
Access controls:
  Grant: Block access
Enable policy: On

Policy 3: Require Compliant Device for Sensitive Apps

yaml
Name: Require Compliant Device
Assignments:
  Users: All users
  Cloud apps: 
    - Microsoft 365 admin center
    - Azure portal
  Conditions:
    Device platforms: All platforms
Access controls:
  Grant: 
    - Require device to be marked as compliant
    OR
    - Require hybrid Azure AD joined device
Enable policy: Report-only (test first)

Phase 6: Configure Self-Service Password Reset ​

Step 6.1: Enable SSPR ​

Azure Portal β†’ Microsoft Entra ID β†’ Password reset

Settings:

yaml
Self-service password reset enabled: All users
Authentication methods:
  Number of methods required: 2
  Methods available:
    - Mobile app notification βœ…
    - Mobile app code βœ…
    - Email βœ…
    - Mobile phone βœ…
    - Security questions βœ…
      - Questions required to register: 5
      - Questions required to reset: 3
Registration:
  Require users to register: Yes
  Days before users asked to reconfirm: 180
Notifications:
  Notify users on password resets: Yes
  Notify admins when other admins reset password: Yes
On-premises integration:
  Write back passwords: Yes (requires Azure AD Connect writeback)

Step 6.2: Configure Password Writeback ​

On Azure AD Connect server:

powershell
# Enable password writeback in Azure AD Connect
# Re-run Azure AD Connect wizard
# Navigate to Optional features β†’ Enable Password writeback

# Verify writeback is enabled
Get-ADSyncConnector | Where-Object {$_.Name -like "*AAD*"} | 
  Get-ADSyncConnectorCapabilities

Phase 7: Configure Privileged Identity Management (PIM) ​

License Required

PIM requires Azure AD Premium P2 license

Step 7.1: Enable PIM ​

Azure Portal β†’ Microsoft Entra ID β†’ Privileged Identity Management β†’ Azure AD roles

Step 7.2: Configure Role Settings ​

Global Administrator Role Settings:

yaml
Role: Global Administrator
Activation:
  Maximum duration: 8 hours
  Require MFA: Yes
  Require justification: Yes
  Require ticket information: Yes
  Require approval: Yes
  Approvers: Security team
Assignment:
  Allow permanent eligible: No
  Expire eligible after: 6 months
  Allow permanent active: No
  Expire active after: Not applicable
Notification:
  Send notifications when members are assigned as eligible
  Send notifications when members are activated

Step 7.3: Assign Eligible Roles ​

PIM β†’ Azure AD roles β†’ Roles β†’ Global Administrator β†’ Add assignments

Step 7.4: Test PIM Activation ​

  1. Sign in as aadmin@contoso.onmicrosoft.com
  2. Navigate to PIM β†’ My roles
  3. Click "Activate" on Global Administrator
  4. Provide justification and ticket number
  5. Wait for approval (if configured)
  6. Role activated for configured duration

Phase 8: Configure Access Reviews ​

Step 8.1: Create Access Review for Privileged Roles ​

Azure Portal β†’ Microsoft Entra ID β†’ Identity Governance β†’ Access reviews β†’ New access review
yaml
Review name: Quarterly Admin Review
Description: Review privileged role assignments
Start date: First day of quarter
Frequency: Quarterly
Duration: 14 days
End: Never
Scope:
  Select users to review: Select users and groups
  Groups: Privileged Admins
  Reviewers: Group owners and managers
Settings:
  Auto apply results: Yes
  If reviewer doesn't respond: Remove access
  Action to apply: Remove membership
Advanced:
  Show recommendations: Yes
  Require reason on approval: Yes
  Mail notifications: Yes
  Reminders: Yes

Phase 9: Testing and Verification ​

Step 9.1: Test User Sign-in Flow ​

  1. Open incognito browser
  2. Go to https://portal.azure.com
  3. Sign in as jsmith@contoso.onmicrosoft.com
  4. Verify MFA prompt appears
  5. Complete MFA enrollment if first time
  6. Verify access granted

Step 9.2: Test SSPR ​

  1. Go to https://aka.ms/sspr
  2. Enter jsmith@contoso.onmicrosoft.com
  3. Complete verification
  4. Reset password
  5. Verify new password works
  6. Verify password synced back to on-premises AD

Step 9.3: Verify Sync Status ​

powershell
# On Azure AD Connect server
Get-ADSyncScheduler

# Should show:
# AllowedSyncCycleInterval : 00:30:00
# CurrentlyEffectiveSyncCycleInterval : 00:30:00
# SyncCycleEnabled : True
# NextSyncCycleStartTime : [Next sync time]

Step 9.4: Check Azure AD Connect Health ​

Azure Portal β†’ Microsoft Entra ID β†’ Azure AD Connect β†’ Connect Health

Verify:

  • Sync service healthy
  • No critical alerts
  • Password hash sync working

Architecture Summary ​

ComponentPurposeLocation
vm-dc01Domain ControllerAzure VM
vm-aadconnectAzure AD ConnectAzure VM
contoso.localOn-premises domainAD DS
contoso.onmicrosoft.comCloud tenantAzure AD
Password Hash SyncIdentity syncHybrid
Conditional AccessAccess controlCloud
PIMPrivileged accessCloud

Cleanup ​

bash
# Delete resource group
az group delete --name $RG_NAME --yes --no-wait

# In Azure AD Portal:
# - Disable Azure AD Connect sync
# - Delete synced user accounts (optional)
# - Remove custom domain (if added)

Key Takeaways ​

  1. Password Hash Sync: Most common sync method, provides cloud authentication
  2. Azure AD Connect: Bridge between on-premises AD and Azure AD
  3. Conditional Access: Zero Trust access control
  4. MFA: Essential security layer
  5. PIM: Just-in-time privileged access
  6. SSPR: Reduces helpdesk tickets

Next Steps ​

  • Implement Pass-through Authentication
  • Configure Seamless SSO
  • Set up Azure AD Application Proxy
  • Implement Azure AD B2B

Released under the MIT License.