Manage reverse DNS zones with Powershell
Manage reverse DNS zones with Powershell
Manage reverse DNS zones with Powershell

The script is a complete tool that will perform the following tasks:

  • list the A records in the domain name defined in the variable $dnsDomainName
  • for each record, check if the reverse zone exist. If not, ask to create the reverse zone (choice between domain and forest-wide replication scope)
  • if the A record does not have a valid reverse record:
    • check if the A record is reachable (ping ok/nok)
    • if the A record is available (ping ok), create the PTR record in the correct zone
    • if the A record is not available (ping nok), the PTR record creation is skipped

The script has been tested successfully in a Windows 2012R2 infrastructure (Active Directory + DNS).

$dnsServer = "mydc01.root.local"
$dnsDomainName = "root.local"
  
$record_A_list = Get-DnsServerResourceRecord -ComputerName $dnsServer -ZoneName $dnsDomainName -RRType A | ? {$_.Hostname -notmatch "@|DomainDnsZones|ForestDnsZones"}
$reverse_zone_list = (Get-DnsServerZone -ComputerName $dnsServer | ? { $_.IsReverseLookupZone -eq $true -and $_.IsAutoCreated -eq $false}).ZoneName
if (-not ($reverse_zone_list)) {
    $record_R_list = ""
    Write-host "No Reverse DNS zone has been found. Analyzing host (A) records to create them..." -ForegroundColor Yellow

    $ReverseZonesToCreate = ($record_A_list.RecordData.IPv4Address.IPAddressToString | % { $_.split(".")[0..2] -join "."}) | select -Unique

    $ReverseZonesToCreate | % {
        "The reverse DNS zone for the NetworkID $_/24 need to be created. Choose the replication scope for this new zone :"
        $netid = "$_/24"    
        $coll = @()

        $b = New-Object System.Management.Automation.Host.ChoiceDescription "&Domain"
        $b.HelpMessage = "Domain-wide replication scope"
        $b | Add-Member -MemberType ScriptMethod -Name Invoke -Value {Add-DnsServerPrimaryZone -NetworkId $netid -ReplicationScope Domain} -force
        $coll+=$b
 
        $c = New-Object System.Management.Automation.Host.ChoiceDescription "&Forest"
        $c.HelpMessage = "Forest-wide replication scope"
        $c | Add-Member -MemberType ScriptMethod -Name Invoke -Value {Add-DnsServerPrimaryZone -NetworkId $netid -ReplicationScope Forest} -force
        $coll+=$c
 
        $q = New-Object System.Management.Automation.Host.ChoiceDescription "&Quit"
        $q.HelpMessage = "Skip the Reverse DNS zone creation"
        $q | Add-Member -MemberType ScriptMethod -Name Invoke -Value {Write-Host "The reverse DNS zone creation for the NetworkID $netid has been skipped" -ForegroundColor DarkGray } -force
        $coll+=$q
        $result = $host.ui.PromptForChoice($title, $message, $coll, 2) 
        $coll[$result].invoke() 
    }
}

$record_R_list = @()
$reverse_zone_list = (Get-DnsServerZone -ComputerName $dnsServer | ? { $_.IsReverseLookupZone -eq $true -and $_.IsAutoCreated -eq $false}).ZoneName
$reverse_zone_list | % {
    try {
        $record_R_list += Get-DnsServerResourceRecord -ComputerName $dnsServer -ZoneName $_ -RRType PTR | ? {$_.Hostname -notmatch "@|DomainDnsZones|ForestDnsZones"}    
    }
    catch {
        "No Reverse DNS zone found. Skipping..."
    }
}

$record_A_list | % {
    $hostname = $_.HostName
    $ipaddress = $_.RecordData.IPv4Address.IPAddressToString
                if ($record_R_list.recordData.PtrDomainName -notcontains "$hostname.$dnsDomainName.") {
                                Write-Host -NoNewline "The following host does not have a valid reverse record in DNS : $hostname.$dnsDomainName."
        
                                $PingStatus = Gwmi Win32_PingStatus -Filter "Address = '$hostname'" | Select-Object StatusCode
                                If ($PingStatus.StatusCode -eq 0){
                                                Write-Host " (online)" -Fore "Green"
                                                $arr = $ipaddress.split(".")
                                                [array]::Reverse($arr)
                                                $reverse_ip = ($arr -join '.') + ".in-addr.arpa"
 
                                                #detect the correct dns reverse lookup zone
                                                $arr_rvr = $reverse_ip.Split(".")
                                                $arr_rvr1 = $arr_rvr[1] + "." + $arr_rvr[2] + "." + $arr_rvr[3] + ".in-addr.arpa"
                                                $arr_rvr2 = $arr_rvr[2] + "." + $arr_rvr[3] + ".in-addr.arpa"
                                                $arr_rvr3 = $arr_rvr[3] + ".in-addr.arpa"

            switch ($reverse_zone_list) {
                {$_ -contains $arr_rvr1} {
                                                                    Write-Host $arr_rvr1 "zone exists in DNS reverse lookup zones"
                                                                    Write-Host "Creating PTR record : $reverse_ip ($hostname.$dnsDomainName.)" -foreground green
                    Add-DnsServerResourceRecordPtr -ComputerName $dnsServer -Name ($arr[0] -join ".")  -ZoneName $arr_rvr1 -PtrDomainName "$hostname.$dnsDomainName"
                                                }
                {$_ -contains $arr_rvr2} {
                                                                    Write-Host $arr_rvr2 "zone exists in DNS reverse lookup zones"
                                                                    Write-Host "Creating PTR record : $reverse_ip ($hostname.$dnsDomainName.)" -foreground green
                    Add-DnsServerResourceRecordPtr -ComputerName $dnsServer -Name ($arr[0..1] -join ".")  -ZoneName $arr_rvr2 -PtrDomainName "$hostname.$dnsDomainName"
                                                }
                {$_ -contains $arr_rvr3} {
                                                                    Write-Host $arr_rvr3 "zone exists in DNS reverse lookup zones"
                                                                    Write-Host "Creating PTR record : $reverse_ip ($hostname.$dnsDomainName.)" -foreground green
                    Add-DnsServerResourceRecordPtr -ComputerName $dnsServer -Name ($arr[0..2] -join ".")  -ZoneName $arr_rvr3 -PtrDomainName "$hostname.$dnsDomainName"
                                                }
            }
                                }
                                Else {
                                                Write-Host " (offline: PTR record creation skipped)"  -Fore "Red"
                                }
                }
    else {
        write-host -foreground DarkGray "$hostname : PTR record already exists"
    }
}

My Powershell script categories

Manage reverse DNS zones with Powershell

Leave a Reply

Your email address will not be published. Required fields are marked *