How to Configure Cross-Forest Trusts in Active Directory on Windows Server 2012 R2

Cross-forest trusts enable users in one Active Directory forest to access resources in another forest, enabling collaboration between organizations, supporting merger and acquisition scenarios, and allowing resource sharing between separate business units with independent IT governance. Windows Server 2012 R2 supports several trust types: forest trusts (for full namespace trust between forests), external trusts (for specific domain-to-domain trust without forest-wide trust), and realm trusts (for non-Windows Kerberos realms). This guide focuses on configuring a full forest trust between two Windows Server 2012 R2 forests.

Prerequisites

– Two separate Active Directory forests, each with at least one Windows Server 2012 R2 Domain Controller
– Both forests at Forest Functional Level Windows Server 2003 or higher
– Forest A: corp.local | Forest B: partner.local
– Network connectivity between both forests’ Domain Controllers (see firewall rules below)
– Enterprise Admin credentials in both forests
– DNS name resolution between both forests (conditional forwarders or stub zones)

Step 1: Configure DNS Name Resolution Between Forests

Trust creation requires that Domain Controllers in each forest can resolve the other forest’s DNS names. Configure conditional forwarders on both sides:

# On corp.local Domain Controller
# Add conditional forwarder for partner.local
Add-DnsServerConditionalForwarderZone -Name "partner.local" `
    -ReplicationScope "Forest" `
    -MasterServers @("10.20.0.10","10.20.0.11")  # partner.local DC IPs

# Verify the forwarder was created
Get-DnsServerConditionalForwarderZone | Format-Table ZoneName, MasterServers -AutoSize

# Test resolution
Resolve-DnsName "dc01.partner.local" -Server "10.20.0.10"
nslookup dc01.partner.local 10.20.0.10

# On partner.local Domain Controller (run separately on that server)
Add-DnsServerConditionalForwarderZone -Name "corp.local" `
    -ReplicationScope "Forest" `
    -MasterServers @("10.10.0.10","10.10.0.11")  # corp.local DC IPs

Resolve-DnsName "dc01.corp.local" -Server "10.10.0.10"

Step 2: Verify Required Network Connectivity

# Test connectivity to partner forest DCs on all required ports
$partnerDC = "dc01.partner.local"
$requiredPorts = @(
    @{Port=53;  Protocol="UDP/TCP"; Service="DNS"},
    @{Port=88;  Protocol="TCP/UDP"; Service="Kerberos"},
    @{Port=135; Protocol="TCP";     Service="RPC Endpoint Mapper"},
    @{Port=139; Protocol="TCP";     Service="NetBIOS Session"},
    @{Port=389; Protocol="TCP/UDP"; Service="LDAP"},
    @{Port=445; Protocol="TCP";     Service="SMB/AD Replication"},
    @{Port=464; Protocol="TCP/UDP"; Service="Kerberos Change Password"},
    @{Port=636; Protocol="TCP";     Service="LDAPS"},
    @{Port=3268;Protocol="TCP";     Service="Global Catalog"},
    @{Port=3269;Protocol="TCP";     Service="Global Catalog SSL"}
)

foreach ($p in $requiredPorts) {
    $result = Test-NetConnection -ComputerName $partnerDC -Port $p.Port
    $status = if ($result.TcpTestSucceeded) { "OPEN" } else { "BLOCKED" }
    Write-Host "Port $($p.Port) ($($p.Service)): $status" `
        -ForegroundColor $(if ($status -eq "OPEN") { "Green" } else { "Red" })
}

Step 3: Create the Forest Trust

Create the forest trust using PowerShell from the corp.local forest. The trust must be created from both sides (or use a two-sided creation with credentials for both forests):

Import-Module ActiveDirectory

# Option 1: Create the trust interactively
# netdom trust corp.local /domain:partner.local /add /twoway /realm

# Option 2: Create using PowerShell (preferred for automation)
# Establish trust from corp.local side
$localForest  = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
$partnerContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext(
    "Forest", "partner.local",
    "PARTNERAdministrator",   # Partner forest admin
    "PartnerAdminPassword"     # Use Read-Host -AsSecureString in production
)
$partnerForest = [System.DirectoryServices.ActiveDirectory.Forest]::GetForest($partnerContext)

# Create a two-way transitive forest trust
$localForest.CreateTrustRelationship($partnerForest, 
    [System.DirectoryServices.ActiveDirectory.TrustDirection]::Bidirectional)

Write-Host "Forest trust created successfully"

# Verify the trust was created
Get-ADTrust -Filter * | Format-Table Name, TrustType, Direction, TrustAttributes -AutoSize

Step 4: Verify Trust with Netdom

# Verify the trust from corp.local
netdom trust corp.local /domain:partner.local /verify

# Check trust direction
netdom trust corp.local /domain:partner.local /query

# Expected output:
# Trust type: Forest (Transitive)
# Trust direction: Bidirectional
# Trust status: The command completed successfully.

# Test trust authentication
netdom trust corp.local /domain:partner.local /USEREXTERNAL:PARTNERtestuser /VerifyTrust

# PowerShell alternative
Get-ADTrust -Filter {Name -eq "partner.local"} | Format-List *

Step 5: Configure Selective Authentication (Recommended)

By default, a forest trust allows any authenticated user from the partner forest to attempt access to any resource in your forest. Selective Authentication restricts this to only specific resources you explicitly grant:

# Enable Selective Authentication on the trust (recommended security practice)
# This requires explicitly granting "Allowed to Authenticate" to partner users/groups
# on specific resources or computers

# Enable via netdom
netdom trust corp.local /domain:partner.local /SelectiveAuth:YES

# Or via PowerShell
Set-ADTrust -Identity "partner.local" -SelectiveAuthentication $true

# Now grant "Allowed to Authenticate" on specific servers that partner users need access to
# This is done via the computer object's Security tab in ADUC or via PowerShell:

$partnerAdminGroup = "PARTNERPartnerAdmins"
$targetServer = Get-ADComputer -Identity "fileserver01"

# Get current ACL on the computer object
$acl = Get-Acl -Path "AD:$($targetServer.DistinguishedName)"

# Add "Allowed to Authenticate" right for the partner group
$partnerSID = (New-Object System.Security.Principal.NTAccount($partnerAdminGroup)).Translate(
    [System.Security.Principal.SecurityIdentifier])

$authRight = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
# "Allowed to Authenticate" GUID: 68b1d179-0d15-4d4f-ab71-46152e79a7bc
$allowedToAuthGuid = New-Object Guid "68b1d179-0d15-4d4f-ab71-46152e79a7bc"
$ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
    $partnerSID,
    [System.DirectoryServices.ActiveDirectoryRights]::ExtendedRight,
    [System.Security.AccessControl.AccessControlType]::Allow,
    $allowedToAuthGuid
)
$acl.AddAccessRule($ace)
Set-Acl -Path "AD:$($targetServer.DistinguishedName)" -AclObject $acl
Write-Host "Allowed to authenticate: $partnerAdminGroup on $($targetServer.Name)"

Step 6: Configure SID Filtering

SID filtering (quarantine) prevents users in the partner forest from using SID history to gain unauthorized access to resources in your forest. This is enabled by default on forest trusts:

# Verify SID filtering is enabled (it should be by default for forest trusts)
netdom trust corp.local /domain:partner.local /quarantine

# Check via PowerShell
Get-ADTrust -Identity "partner.local" | Select-Object SIDFilteringForestAware, SIDFilteringQuarantined

# If you need to allow SID history (not recommended):
# netdom trust corp.local /domain:partner.local /quarantine:NO
# Only disable if you are migrating users and need SID history to work

# For selective cross-forest group membership, SID filtering must remain ON
# and you should use standard group memberships instead of SID history

Step 7: Configure Cross-Forest Group Membership

Import-Module ActiveDirectory

# Add partner forest user to a local resource group
# Universal groups in the resource forest can contain foreign principals

# Create a resource group in corp.local for shared file access
New-ADGroup -Name "SharedDocs-Partners" `
    -GroupScope Universal `
    -GroupCategory Security `
    -Path "OU=Groups,DC=corp,DC=local" `
    -Description "Access group for partner forest users to shared documents"

# Add partner forest user (requires trust to be working)
Add-ADGroupMember -Identity "SharedDocs-Partners" `
    -Members "PARTNERpsmith"

# Verify membership (may require explicit domain specification)
Get-ADGroupMember -Identity "SharedDocs-Partners" | Format-Table Name, objectClass -AutoSize

# Apply the group to a file share ACL
$acl = Get-Acl "D:SharedDocumentsPartner"
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(
    "CORPSharedDocs-Partners","Modify","ContainerInherit,ObjectInherit","None","Allow")
$acl.AddAccessRule($rule)
Set-Acl "D:SharedDocumentsPartner" $acl

Verification

# Full trust verification
Write-Host "=== Cross-Forest Trust Verification ===" -ForegroundColor Cyan

# Trust details
Get-ADTrust -Filter * | Format-Table Name, TrustType, Direction, SelectiveAuthentication, SIDFilteringQuarantined

# Test Kerberos authentication across the trust
klist purge
# Log on as a partner forest user and run:
klist tickets | Select-String "partner.local|corp.local"

# Verify DNS resolution in both directions
Resolve-DnsName "dc01.partner.local"
Resolve-DnsName "dc01.corp.local" -Server "10.20.0.10"

# Check trust health via event log
Get-WinEvent -LogName "Microsoft-Windows-Kerberos/Operational" -MaxEvents 20 |
    Where-Object { $_.Message -like "*partner*" } | 
    Format-Table TimeCreated, Message -Wrap

Summary

Cross-forest trusts on Windows Server 2012 R2 are powerful tools for enabling collaboration between organizations while maintaining security boundaries. The deployment process requires DNS conditional forwarders for name resolution, network connectivity on all AD ports, creating the bidirectional forest trust, enabling Selective Authentication to limit access scope, maintaining SID filtering to prevent privilege escalation via SID history, and configuring explicit group membership for cross-forest resource access. For mergers and acquisitions, these trusts bridge two separate identity stores without requiring migration, allowing gradual consolidation while maintaining operational continuity.