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

Large enterprises, mergers, and acquisition scenarios frequently require resources in one Active Directory forest to be accessible to users in a completely separate forest. Active Directory cross-forest trusts solve this by establishing a secure Kerberos referral path between forests, allowing users authenticated in one forest to receive Kerberos tickets for resources in the other. Windows Server 2025 supports all four trust types — external, forest, shortcut, and realm — each suited to different scenarios. A forest trust is the most comprehensive option between two Windows forests: it transitively covers all domains in both forests and supports features such as selective authentication, SID filtering, and UPN routing. This tutorial covers the full lifecycle of a bidirectional forest trust: DNS preparation, trust creation, selective authentication, SID filtering, and troubleshooting with nltest.

Prerequisites

  • Two separate AD forests: contoso.com (local forest) and fabrikam.com (remote forest), each running at Windows Server 2016 or later functional level.
  • Enterprise Admin credentials in both forests.
  • Network connectivity between DCs in both forests (TCP/UDP 88 Kerberos, TCP 135 RPC, TCP/UDP 389 LDAP, TCP 636 LDAPS, TCP/UDP 53 DNS, TCP 445 SMB, RPC dynamic ports 49152–65535).
  • DNS resolution between forests: each forest DNS must be able to resolve the other’s domain names (conditional forwarders or secondary zones).
  • Windows Firewall rules permitting the above ports between DC subnets in both forests.

Step 1: Verify DNS Resolution Between Forests

Active Directory trusts depend entirely on DNS. Before creating a trust, both forests must resolve each other’s names. Set up conditional forwarders on the DCs in each forest pointing to the other forest’s DNS servers.

# Run on a DC in contoso.com — add conditional forwarder for fabrikam.com
Add-DnsServerConditionalForwarderZone `
    -Name "fabrikam.com" `
    -MasterServers "10.1.0.10","10.1.0.11" `
    -ReplicationScope "Forest"   # Replicate to all DNS servers in contoso.com forest

# Run on a DC in fabrikam.com — add conditional forwarder for contoso.com
Add-DnsServerConditionalForwarderZone `
    -Name "contoso.com" `
    -MasterServers "192.168.1.10","192.168.1.11" `
    -ReplicationScope "Forest"

# Verify resolution from contoso.com DC
Resolve-DnsName -Name "dc01.fabrikam.com" -Type A
Resolve-DnsName -Name "_ldap._tcp.dc._msdcs.fabrikam.com" -Type SRV

# Verify resolution from fabrikam.com DC
Resolve-DnsName -Name "dc01.contoso.com" -Type A -Server "10.1.0.10"

# Check network connectivity — Kerberos and LDAP ports must be reachable
Test-NetConnection -ComputerName "dc01.fabrikam.com" -Port 88
Test-NetConnection -ComputerName "dc01.fabrikam.com" -Port 389
Test-NetConnection -ComputerName "dc01.fabrikam.com" -Port 445

Step 2: Understand Trust Types

Before creating the trust, select the correct type for your scenario:

  • Forest trust: Bidirectional or one-way trust between two entire forests. Supports all domains in both forests (transitive within each forest). Requires both forests at Windows Server 2003 or higher functional level. Best for mergers and long-term inter-company collaboration.
  • External trust: One-way or two-way trust between a single domain in one forest and a single domain in another. Non-transitive. Suitable for isolated resource sharing without full forest trust exposure.
  • Shortcut trust: Between two domains within the same forest to shorten the Kerberos referral chain. Speeds up authentication in large multi-domain forests.
  • Realm trust: Between an AD domain and a non-Windows Kerberos realm (e.g., MIT Kerberos on Linux). One-way or two-way, transitive or non-transitive.

Step 3: Create the Bidirectional Forest Trust

The New-ADTrust cmdlet requires a credential object for the remote forest. Both sides of the trust are created in a single command when you supply credentials for the remote forest.

# Run on a DC in contoso.com with Enterprise Admin credentials for both forests

Import-Module ActiveDirectory

# Credential for the remote forest (fabrikam.com) Enterprise Admin
$remoteCred = Get-Credential -Message "Enter Enterprise Admin for fabrikam.com"
# Username format: FABRIKAMAdministrator or [email protected]

# Create bidirectional forest trust
# -Name: the DNS name of the remote forest root domain
# -TrustType: Forest (covers all domains in both forests transitively)
# -TrustDirection: Bidirectional (both forests authenticate users from the other)
New-ADTrust `
    -Name "fabrikam.com" `
    -TrustType Forest `
    -TrustDirection Bidirectional `
    -TargetCredential $remoteCred `
    -Verbose

# Verify the trust was created on both sides
Get-ADTrust -Filter * | Select-Object Name, TrustType, TrustDirection, `
    TrustAttributes, SelectiveAuthentication

# On the fabrikam.com side, verify the incoming trust
# (Run on a fabrikam.com DC)
# Get-ADTrust -Filter * | Select-Object Name, TrustType, TrustDirection

Step 4: Configure Selective Authentication

By default, a forest trust uses forest-wide authentication, which allows any authenticated user from the trusted forest to be automatically authenticated for resources in the trusting forest — exactly as if they were a local user. Selective authentication is more restrictive: users from the trusted forest can only access a resource server if they have been explicitly granted the “Allowed to Authenticate” extended right on that server object in AD. Enable selective authentication for the tightest security posture.

# Enable selective authentication on the trust in contoso.com
# (Controls access to contoso.com resources by fabrikam.com users)
Set-ADTrust `
    -Identity "fabrikam.com" `
    -SelectiveAuthentication $true

# Repeat on the fabrikam.com side if the trust is bidirectional
# (Controls access to fabrikam.com resources by contoso.com users)
# Run on a fabrikam.com DC:
# Set-ADTrust -Identity "contoso.com" -SelectiveAuthentication $true

# After enabling selective authentication, grant a specific user or group
# the "Allowed to Authenticate" permission on the target resource server

# First, find the computer account's distinguished name
$serverDN = (Get-ADComputer -Identity "SRV-FILESERVER01").DistinguishedName

# Grant Allowed to Authenticate to a fabrikam.com security group
# The group must be visible (use the forest trust SID mapping or a domain local group)
$trustedGroup = "FABRIKAMFileshareUsers"

# Use dsacls to grant the extended right
dsacls $serverDN /G "${trustedGroup}:CA;Allowed to Authenticate"

# Or use PowerShell ACL manipulation:
$acl = Get-Acl -Path "AD:$serverDN"
$groupSID = (New-Object System.Security.Principal.NTAccount($trustedGroup)).Translate(
    [System.Security.Principal.SecurityIdentifier])
$allowedToAuth = [System.DirectoryServices.ActiveDirectoryRights]::ExtendedRight
$inheritType    = [System.DirectoryServices.ActiveDirectorySecurityInheritance]::None
$extRight       = [GUID]"68b1d179-0d15-4d4f-ab71-46152e79a7bc" # Allowed to Authenticate GUID
$ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
    $groupSID, $allowedToAuth, "Allow", $extRight, $inheritType)
$acl.AddAccessRule($ace)
Set-Acl -Path "AD:$serverDN" -AclObject $acl
Write-Host "Allowed to Authenticate granted to $trustedGroup on $serverDN"

Step 5: Understand SID Filtering and SID History Quarantine

SID filtering prevents users from the trusted forest from using SID history attributes to elevate privileges in the trusting forest. Windows Server 2025 enables SID filtering (quarantine) on forest trusts by default to protect against SID-based privilege escalation attacks. Be aware of this behaviour when migrating accounts between forests.

# Check current SID filtering status on the trust
Get-ADTrust -Identity "fabrikam.com" | `
    Select-Object Name, SIDFilteringForestAware, SIDFilteringQuarantined

# SIDFilteringQuarantined = True  means SID history is blocked across the trust
# SIDFilteringForestAware = True  means the trust respects forest claim transformations

# To DISABLE SID filtering (NOT recommended in production — only during migration)
# netdom trust contoso.com /domain:fabrikam.com /quarantine:No /UserO:Administrator /PasswordO:*

# To check which SID filtering mode is active (using netdom)
netdom trust contoso.com /domain:fabrikam.com /quarantine:Confirm

# Enable forest claim transformation (allows user claims from fabrikam.com to be
# passed to contoso.com resources — needed for Dynamic Access Control)
# This requires a claim transformation policy object
# New-ADClaimTransformPolicy -Name "AllowAllClaims" -AllowAllClaims
# Set-ADTrust -Identity "fabrikam.com" -IncomingClaimTransformationPolicy "AllowAllClaims"

Step 6: Test Cross-Forest Kerberos Authentication

When a user in fabrikam.com accesses a resource in contoso.com, Kerberos issues cross-forest referral tickets. The process goes: client contacts fabrikam.com KDC → receives referral to contoso.com KDC → receives service ticket for target server. Verify this chain works.

# On a machine joined to fabrikam.com — attempt to access a contoso.com share
# The user account must have NTFS/share permissions and (if selective auth) Allowed to Authenticate

# Test UNC access
Test-Path "\SRV-FILESERVER01.contoso.comSharedDocs"

# Inspect the Kerberos tickets in the cache — should show cross-realm TGT referrals
klist
# Look for:
# Server: krbtgt/CONTOSO.COM @ FABRIKAM.COM  (cross-realm referral TGT)
# Server: cifs/SRV-FILESERVER01.contoso.com  (service ticket)

# Purge and re-test if needed
klist purge
net use "\SRV-FILESERVER01.contoso.comSharedDocs" /user:FABRIKAMjsmith

# Check on the contoso.com DC for trust-related logon events
Get-WinEvent -ComputerName "DC01.contoso.com" -LogName Security `
    -FilterXPath "*[System[EventID=4768] and EventData[Data[@Name='TargetDomainName']='FABRIKAM.COM']]" `
    -MaxEvents 20 | Select-Object TimeCreated, Message

Step 7: Troubleshoot Trust Relationships with nltest

# Verify the secure channel on the local domain
nltest /sc_verify:contoso.com

# Verify the cross-forest trust relationship (queries both sides)
nltest /sc_verify:fabrikam.com

# Query the trust status explicitly
nltest /trusted_domains
# Look for "fabrikam.com" with flags including DIRECT_OUTBOUND or DIRECT_INBOUND

# Force a secure channel reset if trust verification fails
nltest /sc_reset:fabrikam.com

# Get detailed DC discovery info for the remote forest
nltest /dsgetdc:fabrikam.com /force /kdc /avoidself

# Check DNS resolution failures in trust context
nltest /dsgetdc:fabrikam.com /discover

# Verify that trust is functional end-to-end using netdom
netdom trust contoso.com /domain:fabrikam.com /verify

# If you receive "The trust relationship between the primary domain and the trusted domain failed":
# 1. Confirm DNS conditional forwarders resolve correctly
# 2. Confirm firewall rules allow all required ports
# 3. Check time synchronisation (Kerberos requires < 5 minute skew)
w32tm /query /status   # Check NTP source and offset
w32tm /resync /force   # Force time resync

# Audit trust authentication events
Get-WinEvent -LogName "Security" -FilterXPath `
    "*[System[(EventID=4769 or EventID=4768)]]" -MaxEvents 30 | `
    Select-Object TimeCreated, @{N="Message";E={$_.Message.Substring(0,200)}}

Step 8: Manage and Remove Trusts

# List all trusts in the current forest
Get-ADTrust -Filter * | Format-Table Name, TrustType, TrustDirection, `
    TrustAttributes, SelectiveAuthentication -AutoSize

# Update trust properties (e.g., change to one-way inbound)
Set-ADTrust -Identity "fabrikam.com" -TrustDirection Inbound

# Remove the trust (removes from contoso.com side only — repeat on fabrikam.com)
# WARNING: Users from fabrikam.com will immediately lose access to contoso.com resources
Remove-ADTrust -Identity "fabrikam.com" -Confirm:$true

# To cleanly remove both sides simultaneously, use netdom:
# netdom trust contoso.com /domain:fabrikam.com /remove /twoway `
#     /UserO:[email protected] /PasswordO:* `
#     /UserD:[email protected] /PasswordD:*

Conclusion

Cross-forest trusts on Windows Server 2025 provide a controlled and auditable pathway for inter-organisation or post-merger resource sharing without collapsing two forests into one. The key to a secure deployment is enabling selective authentication on the trust rather than relying on forest-wide authentication, explicitly granting the “Allowed to Authenticate” extended right only on the servers that cross-forest users need to reach, and leaving SID filtering (quarantine) enabled to block SID history-based privilege escalation. DNS is the most common source of trust failures — always validate bidirectional name resolution before attempting trust creation. The nltest /sc_verify and netdom trust /verify commands are your first diagnostic tools when authentication across the trust fails, and checking for Kerberos time skew should always be part of your troubleshooting checklist. With proper planning and the PowerShell-driven workflow described here, cross-forest trusts can be deployed, documented, and maintained with the same rigour as any other piece of critical identity infrastructure.