The _msdcs subdomain is a fundamental component of Active Directory DNS infrastructure. Unlike regular DNS zones, it contains specialized SRV records that enable core AD functions including:
- Domain controller location (_ldap._tcp.dc._msdcs)
- Global catalog services (_gc._tcp)
- Kerberos authentication (_kerberos._tcp)
- Site-specific service records
When scavenging is enabled on the _msdcs zone, you risk removing critical records that may appear "stale" but are actually essential:
# Example of critical _msdcs records that should never be scavenged _ldap._tcp.dc._msdcs.domain.com. 600 IN SRV 0 100 389 dc1.domain.com. _kerberos._tcp.dc._msdcs.domain.com. 600 IN SRV 0 100 88 dc2.domain.com. _gc._tcp.domain.com. 600 IN SRV 0 100 3268 gc1.domain.com.
These records are dynamically registered by domain controllers and may appear unchanged for extended periods while remaining fully functional.
To safely configure scavenging while protecting _msdcs:
- Disable scavenging specifically for _msdcs zone:
# PowerShell to disable scavenging on _msdcs zone Set-DnsServerZoneAging -Name "_msdcs.domain.com" -Aging $false -ScavengeServers $null
- Configure appropriate scavenging settings for other zones:
# Recommended scavenging settings for non-_msdcs zones Set-DnsServerScavenging -ScavengingState $true -RefreshInterval 7.00:00:00 -NoRefreshInterval 7.00:00:00 -ScavengingInterval 7.00:00:00
If scavenging has already occurred in _msdcs zone, check for these symptoms:
- Authentication failures across sites
- DFS replication issues
- Unexpected application connection problems
To verify and repair:
# Check DNS records health dcdiag /test:dns /v /e # Force registration of critical records nltest /dsregdns # Alternative method for single DC Register-DnsClient
Implement these monitoring checks:
# PowerShell script to monitor _msdcs records $criticalRecords = @( "_ldap._tcp.dc._msdcs", "_kerberos._tcp.dc._msdcs", "_gc._tcp" ) foreach ($record in $criticalRecords) { $result = Resolve-DnsName -Name "$record.$env:USERDNSDOMAIN" -Type SRV if (-not $result) { Write-Warning "Critical _msdcs record missing: $record" } }
Consider implementing DNS audit logging to track changes to critical records:
# Enable DNS debug logging Set-DnsServerDiagnostics -All $true -Notifications $true -Queries $true -Answers $true -Updates $true -Transfers $true
The _msdcs domain is a special DNS subdomain that contains crucial Active Directory service location records. Unlike regular DNS zones, it stores SRV records that enable core AD functions like:
- Domain controller location (_ldap._tcp.dc._msdcs)
- Kerberos authentication (_kerberos._tcp.dc._msdcs)
- Global catalog services (_gc._tcp)
When scavenging is enabled on the _msdcs zone, it introduces several risks:
# Example PowerShell to check scavenging settings
Get-DnsServerScavenging -ComputerName DC01 |
Select-Object * | Format-List
Common issues we've seen in production environments:
- Premature removal of SRV records before tombstone lifetime expires
- Accidental deletion of records for domain controllers with temporary network issues
- Broken replication when DCs try to reference scavenged records
For proper _msdcs zone management:
# Disable scavenging specifically for _msdcs zone
Set-DnsServerZoneAging -Name "_msdcs.yourdomain.com"
-Aging $false
-ComputerName DC01
Instead of scavenging, implement these alternatives:
- Regular monitoring of DNS records using:
- Manual cleanup during DC decommissioning
- Automated verification scripts
Get-DnsServerResourceRecord -ZoneName "_msdcs.yourdomain.com" -RRType SRV
If you suspect scavenging has caused problems:
# Check DNS event logs for scavenging activities
Get-WinEvent -LogName "DNS Server" |
Where-Object {$_.Id -eq 2501 -or $_.Id -eq 2502} |
Format-List -Property TimeCreated,Message
Key recovery steps include:
- Restoring from DNS backup (if configured)
- Running
net stop netlogon
followed bynet start netlogon
to rebuild records - Forcing replication with
repadmin /syncall
For large environments, consider these additional measures:
# Create a monitoring script for _msdcs records
$criticalRecords = @(
"_ldap._tcp.dc._msdcs",
"_kerberos._tcp.dc._msdcs",
"_gc._tcp"
)
foreach ($record in $criticalRecords) {
try {
$test = Resolve-DnsName -Name "$record.yourdomain.com" -Type SRV -ErrorAction Stop
Write-Host "$record - OK"
} catch {
Write-Warning "$record - MISSING"
}
}