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
- Active Directory
- Cluster
- Database
- Exchange
- Files and folders
- Hardware
- Network
- Operating System
- PKI
- SCCM
- Service and process
- Tips
- VMWare
Manage reverse DNS zones with Powershell
Hi Niko,
Thanks for sharing this great script, this is exactly I was looking for.
My only problem is that after the script goes through the PTR records and finds the one that already exists, it’s like starting over and then adds another domain name to it.
So which was originally “something.xxx.lan” – “PTR record already exists”, next time it says “Creating PTR record” and it changes to “something.xxx.lan.xxx.lan”
Can you please help me on this?
Thank you in advance.