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 β
# 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 β
# 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-addcPhase 2: Deploy Domain Controller β
Step 2.1: Create Domain Controller VM β
# 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 β
# 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 β
# 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:
# 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 automaticallyStep 2.5: Create Test Users and Groups β
After DC restarts, reconnect via Bastion:
# 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, UserPrincipalNamePhase 3: Configure Azure AD Connect β
Step 3.1: Create Azure AD Connect Server β
# 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:
# Join domain
$DomainCred = Get-Credential # Enter contoso\domainadmin
Add-Computer -DomainName "contoso.local" -Credential $DomainCred -RestartStep 3.3: Prepare Azure AD β
Before installing Azure AD Connect, configure Azure AD:
Add Custom Domain (optional for production):
- Azure Portal β Microsoft Entra ID β Custom domain names
- Add your verified domain
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:
- Download Azure AD Connect:
# 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- 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 β
# 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-ADSyncConnectorStatisticsIn 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 β NoStep 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 methodsEnable 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 locationsCreate 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 policyName: 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: OnPolicy 2: Block Legacy Authentication
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: OnPolicy 3: Require Compliant Device for Sensitive Apps
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 resetSettings:
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:
# 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-ADSyncConnectorCapabilitiesPhase 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 rolesStep 7.2: Configure Role Settings β
Global Administrator Role Settings:
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 activatedStep 7.3: Assign Eligible Roles β
PIM β Azure AD roles β Roles β Global Administrator β Add assignments- Select user: aadmin@contoso.onmicrosoft.com
- Assignment type: Eligible
- Assignment duration: 6 months
Step 7.4: Test PIM Activation β
- Sign in as aadmin@contoso.onmicrosoft.com
- Navigate to PIM β My roles
- Click "Activate" on Global Administrator
- Provide justification and ticket number
- Wait for approval (if configured)
- 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 reviewReview 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: YesPhase 9: Testing and Verification β
Step 9.1: Test User Sign-in Flow β
- Open incognito browser
- Go to https://portal.azure.com
- Sign in as jsmith@contoso.onmicrosoft.com
- Verify MFA prompt appears
- Complete MFA enrollment if first time
- Verify access granted
Step 9.2: Test SSPR β
- Go to https://aka.ms/sspr
- Enter jsmith@contoso.onmicrosoft.com
- Complete verification
- Reset password
- Verify new password works
- Verify password synced back to on-premises AD
Step 9.3: Verify Sync Status β
# 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 HealthVerify:
- Sync service healthy
- No critical alerts
- Password hash sync working
Architecture Summary β
| Component | Purpose | Location |
|---|---|---|
| vm-dc01 | Domain Controller | Azure VM |
| vm-aadconnect | Azure AD Connect | Azure VM |
| contoso.local | On-premises domain | AD DS |
| contoso.onmicrosoft.com | Cloud tenant | Azure AD |
| Password Hash Sync | Identity sync | Hybrid |
| Conditional Access | Access control | Cloud |
| PIM | Privileged access | Cloud |
Cleanup β
# 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 β
- Password Hash Sync: Most common sync method, provides cloud authentication
- Azure AD Connect: Bridge between on-premises AD and Azure AD
- Conditional Access: Zero Trust access control
- MFA: Essential security layer
- PIM: Just-in-time privileged access
- SSPR: Reduces helpdesk tickets
Next Steps β
- Implement Pass-through Authentication
- Configure Seamless SSO
- Set up Azure AD Application Proxy
- Implement Azure AD B2B