PowerShell and Tombstoned DNS Records

I recently ran into a situation where DNS A and PTR records were mysteriously disappearing in a Windows 2008 R2 Forest.  I searched and searched for scripts to assist me in trying to “track” this problem by using event logs and even created filters with a logging product my company owns, with little luck.

The following two links are quite helpful when trying to troubleshoot, understand, setup, DNS and DHCP, etc.



However, a bit of a hint.  There’s some information left out!  First, you have to read Ace’s post very carefully and understand the PROCESS of how a DNS record is deleted.  In fact, don’t use the word delete.  A record isn’t deleted, it’s tombstoned, not visible and you are unable to query it through any DNS methods.  When the record goes “away”, the AD object is “cleaned/cleared” from AD.  To be simplistic, it’s a two step process.

The other information is, don’t just look for event ID 4662!  If you read Ace’s article and begin to understand the process, what’s happening is an attribute is changing on the record itself!  You also need to pay attention to event ID 5136 and 5137.

Now, you say, if the Windows security event logs don’t necessarily give you information on the actual record deletion, but only a change in the dnstombstone attribute, then is there a better way?

Certainly!  PowerShell to the rescue!  In fact, forget about the DNS console and the event logs altogether!

This short little script queries AD itself, looks at the attribute dNSTombstoned and the attribute whenChanged, creates a csv file and then emails it.  You then can see a report of any record (object DN) and when it was last changed.  You can limit the scope by altering the DN. Notice I’m using the root DN for all my zones so I’m including any reverse zones as well as additional forward zones.

Resist the urge to use the “-IncludeAllProperties” switch when using anything that queries. You can do that to dig down while developing your scripts (hopefully in a test environment), but to speed up your scripts, just include only the specific properties that you are going to use.

It’s simple enough to set up a scheduled task in windows to allow this script to run as often as you like.  Please ignore the lack of error handling here, I’m trying to keep it plain and simple.

Note the requirement of PowerShell V2 and PsSnapIn quest.activeroles.admanagement.

Also note that it’s only necessary to use the script during troubleshooting and not on a continual basis.  Probably won’t hurt anything, but if it’s not necessary to run it, why waste resources?

Also, as always, please test scripts you find on the internet in a test lab and fully understand them before bringing them into your production environments.

   Script to generate report on DNS records marked tombstoned
   This script queries AD objects to find DNS records marked as tombstoned, creates a CSV file with the name of the record and when the record was changed to tombstoned.
   It then emails it to a list of individuals
	PsSnapIn quest.activeroles.admanagement 
   PS c:\foo> .\Start-DNSTombstoneReport.ps1

$TestQADSnapin = get-pssnapin | where { $_.Name -eq "Quest.ActiveRoles.ADManagement"} 
if($TestQADSnapin -eq $null){
	add-pssnapin -Name Quest.ActiveRoles.ADManagement -ErrorAction SilentlyContinue
$CSVFile = "C:\temp\dnsTombstoneReport.csv"

$Result = Test-Path $CSVFile
If ($Result){
	Remove-Item $CSVFile -Force

$TombstonedRecords = Get-QADObject -searchroot 'CN=MicrosoftDNS,DC=ForestDnsZones,DC=MyDomain,DC=Local' -IncludedProperties dNSTombstoned,name,distinguishedName,whenchanged  -SizeLimit 0 -ShowProgress:$False | Where {($_.dNSTombstoned -eq $true) -and ($_.name -NotLike "_*")} | select-object distinguishedName,@{name="DateChanged";expression={$_.whenChanged.ToShortDateString()}}
If ($TombstonedRecords){
	$TombstonedRecords | Sort-Object -Descending DateChanged | Export-Csv $CSVFile -NoTypeInformation
	Send-MailMessage -From "SomeGuy@MyDomain.Local" -To "SomeGuy@MyDomain.Local"  -subject "DNS Tombstone Records Report" -smtpServer "smtp.MyDomain.Local" -attachments $CSVFile
	Remove-Item $CSVFile