PowerShell and _MSDCS Recovery

Oh, no! Someone's blatted the _MSDCS zone from DNS! The _MSDCS zone hosts the domain controller locator DNS resource records for all the domain controllers in an Active Directory forest - it's a key part of how clients find domain controller services. This unfortunate deletion has been replicated to all domain controllers. What to do?

 

Call your friendly, neighbourhood PowerShell! Here's a simple suggestion:

  1. configure all DCs to use a single domain controller as their primary DNS server
  2. use PowerShell to recreate the zone
  3. use PowerShell to make each DC re-register its SRV records to the new zone
  4. restore original DNS settings to DCs

 

More on step 1...

Make sure you make a note of the existing DNS settings on each DC. Here's a simple bit of PowerShell to collect that information:

(Get-ADForest).Domains | ForEach-Object {

Get-ADDomainController -Filter * -Server $_ | ForEach-Object {

Get-CimInstance -Class Win32_NetworkAdapterConfiguration -Filter 'IPEnabled=TRUE' -ComputerName $_ |

Format-Table PSComputerName,DnsServerSearchOrder -Wrap -AutoSize |

Out-File .\DC_DNS_Settings.txt -Append

}

}

 

We query the forest to get a list of domains. We then get every domain controller for each domain. Each domain controller is queried for the Win32_NetworkAdapterConfiguration class, using Get-CimInstance, and we ask for the DnsServerSearchOrder property which contains a list of configured DNS servers for each IPEnabled adapter. This is then dumped out to a file for future reference.

 

More on step 2...

Perform the following action on the designated pimary DNS server: 

Add-DnsServerPrimaryZone -ComputerName "dc01.contoso.com" -DynamicUpdate Secure -Name "_msdcs.contoso.com" -ReplicationScope Forest -Verbose

  

 
More on step 3...

Use Invoke-Command to remotely restart the Netlogon service on all domain controllers - this will recreate the necessary DNS resource records:

(Get-ADForest).Domains | ForEach-Object {

Get-ADDomainController -Filter * -Server $_ | ForEach-Object {

Invoke-Command -ComputerName $_ -ScriptBlock {

Restart-Service Netlogon

}

}

}

 

Finally...

Test, check and tidy-up. Be patient!

"...How poor are they that have not patience!
What wound* did ever heal but by degrees?
Thou know'st we work by wit, and not by witchcraft;
And wit depends on dilatory time..."

*On the subject of wounds, my regular readers may have noticed that I failed to post last Friday, disrupting my usual blogging cadence. This is because of a 'DIY incident'. That's all I'm saying...