Get and delete DNS A and PTR records via PowerShell

My Remote Desktop Session Host build process is now pretty slick. I can easily rebuild a lot of RDSH VMs very quickly. The process basically involved powering off the existing VM, deleting both it and its Active Directory account, and provisioning a new VM. However this causes a slight issue because the AD DNS record is left behind from the old VM, with the security to update it still assigned to the old VM. This means that if I change the allocated IP address for an RDSH server as part of the rebuild, the new VM doesn’t have permission to update the DNS A and PTR records for itself (security is done by AD SID, DNS just works on names/IP addresses).

So, time to use Get-DnsServerResourceRecord and Remove-DnsServerResourceRecord.

Doing the A record is easy:

$NodeToDelete = "rdsh01"
$DNSServer = "dns01.rcmtech.co.uk"
$ZoneName = "rcmtech.co.uk"
$NodeDNS = $null
$NodeDNS = Get-DnsServerResourceRecord -ZoneName $ZoneName -ComputerName $DNSServer -Node $NodeToDelete -RRType A -ErrorAction SilentlyContinue
if($NodeDNS -eq $null){
    Write-Host "No DNS record found"
} else {
    Remove-DnsServerResourceRecord -ZoneName $ZoneName -ComputerName $DNSServer -InputObject $NodeDNS -Force
}

So we try and get the DNS record we’re interested in. If the record is found, we delete it. I was originally doing this not using an -ErrorAction of “SilentlyContinue” but a “Stop”, which worked to a point but was inconsistent: If the DNS name I was trying to get had never existed (i.e. I made something up) it worked fine, but if I created an A record, ran the script to delete it, then tried the script again with the same DNS name to delete, the Get-DnsServerResourceRecord didn’t error. It didn’t return anything either, and hence why this is coded to use an if statement to check whether $NodeDNS is $null or not, rather than using a try/catch as was my original plan.

The PTR record is a little more fiddly. Now, getting PTR info via nslookup is easy:

C:\> nslookup 192.168.1.123
Server: dns01.rcmtech.co.uk
Address: 192.168.1.10

Name: rdsh01.rcmtech.co.uk
Address 192.168.1.123

Not so with PowerShell… You have to specify the reverse lookup zone, and also give the right bit of the IP address in the right order.

For example, I want to find the name of the machine with IP address 192.168.1.123, and let’s assume my internet class B address range is 192.168.0.0.

Get-DnsServerResourceRecord -ZoneName "168.192.in-addr.arpa" -ComputerName "dns01.rcmtech.co.uk" -Node "123.1" -RRtype Ptr

…nice. You can’t just pass it the full IP address as you can with nslookup. Oh no, we have to be a little more “creative”.

What I’ve ended up doing is using Get-DnsServerResourceRecord to look up the A record of the server to get its IP address, split this into an array – each element containing an octet of the address, then delete the PTR record and finally the A record.

param($NodeToDelete= "")
if($NodeToDelete-eq ""){
    Write-Error "You need to specify a name to delete" -Category NotSpecified -CategoryReason "Need a name to delete" -CategoryTargetName "Missing parameter" -CategoryTargetType "DNS name"
    return
}

$DNSServer = "dns01.rcmtech.co.uk"
$ZoneName = "rcmtech.co.uk"
$ReverseZoneName = "168.192.in-addr.arpa"
$NodeARecord = $null
$NodePTRRecord = $null

Write-Host "Check for existing DNS record(s)"
$NodeARecord = Get-DnsServerResourceRecord -ZoneName $ZoneName -ComputerName $DNSServer -Node $NodeToDelete -RRType A -ErrorAction SilentlyContinue
if($NodeARecord -eq $null){
    Write-Host "No A record found"
} else {
    $IPAddress = $NodeARecord.RecordData.IPv4Address.IPAddressToString
    $IPAddressArray = $IPAddress.Split(".")
    $IPAddressFormatted = ($IPAddressArray[3]+"."+$IPAddressArray[2])
    $NodePTRRecord = Get-DnsServerResourceRecord -ZoneName $ReverseZoneName -ComputerName $DNSServer -Node $IPAddressFormatted -RRType Ptr -ErrorAction SilentlyContinue
    if($NodePTRRecord -eq $null){
        Write-Host "No PTR record found"
    } else {
        Remove-DnsServerResourceRecord -ZoneName $ReverseZoneName -ComputerName $DNSServer -InputObject $NodePTRRecord -Force
        Write-Host ("PTR gone: "+$IPAddressFormatted)
    }
    Remove-DnsServerResourceRecord -ZoneName $ZoneName -ComputerName $DNSServer -InputObject $NodeARecord -Force
    Write-Host ("A gone: "+$NodeARecord.HostName)
}
This entry was posted in PowerShell, Scripting, Windows and tagged , , , , , , , , , , , , . Bookmark the permalink.

2 Responses to Get and delete DNS A and PTR records via PowerShell

  1. DanP. says:

    I think you have to account for ptr’s in any reverse zone before you declare there isn’t a ptr. I have yet to see an organization that is really strict on creating a reverse zone for every subnet.

    Test the last three octets, then two, then one.

    $reversezone = $ip -replace ‘^(\d+)\.(\d+)\.(\d+)\.(\d+)$’,’$3.$2.$1.in-addr.arpa’

  2. Alan says:

    Hi Guys, I Just created on Script using PtrDomainName as key to filter and delete Ptr records, I think is better becouse we don´t need to searh for Ip address in the code…

    In My case I deleted all HostNames starting with 12 numbers, that is garbage in my DNS.
    But you can adapt to Hostname geting by the main Zone.

    $zone=”20.10.in-addr.arpa”
    $DNSServer=”SERVER”
    $recordtype=”Ptr”

    $records=Get-DnsServerResourceRecord -ZoneName “$zone” -ComputerName $DNSServer |
    Where-Object {$_.RecordType -eq “$recordtype” -and $_.RecordData.PtrDomainName.Substring(0,12) -match “^[0-9]*$”}

    Foreach ($record in $records)
    {
    # Remove the DNS record by filtering

    Try
    {
    $hostadi=$record.HostName
    $info=$record.RecordData.PtrDomainName
    Remove-DnsServerResourceRecord -ZoneName $zone -ComputerName $DNSServer -Force -RRType “$recordtype” -Name $record.HostName

    Write-Host (“[{0}] deleted record name is : $hostadi ($info)” -f (Get-Date))
    (“[{0}] delete record name: $hostadi ($info)” -f (Get-Date)) | out-file “E:\LimpaDNS\LimpaPTR.txt” -Append
    }
    Catch
    {
    Write-Host (“[{0}] Cannot delete the record: $hostadi ($info)” -f (Get-Date))
    (“[{0}] Cannot delete the record name: $hostadi ($info)” -f (Get-Date)) | out-file “E:\LimpaDNS\LimpaPTR.txt” -Append
    }

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s