Jump to page sections
Last edited: 2023-05-18. Originally written sometime around 2013-2014 (estimate).

The main script uses the PowerShell module DnsShell from Codeplex (NB! Dead link! DnsShell is no longer on Codeplex and I think even Codeplex itself has been discontinued), which you will need to download to use that script, and it finds duplicate PTR records on a Windows DNS server.

DnsShell uses WMI calls. It was tested against a Windows Server 2008 R2 DNS server, but should also work against 2003 R2. Not tested against 2012 and up; feel free to provide feedback if you test it (svendsentech@gmail.com).

I also tossed in a version that can be adapted to not rely on DnsShell (comment added 2023-05-18: And it's a good thing I did! Because DnsShell no longer is easily available), but you will then somehow need to get the reverse zones into a file or variable in the correct format. It can also be used with DnsShell to produce slightly different-looking results from what the main script does.

The script is written for "interactive use", so it displays results to the screen. You can edit it to suit your needs. It also exports a CSV if it finds any duplicate PTR records (apparently it always has a positive count, so it gets written anyway).

Multiple host names for the same PTR record are displayed separated by a semicolon in the data.

It was tested with PowerShell v3, but should work with v2 (the latter being the default in Server 2008 R2 and Windows 7).

Download Main Script

Get-DupePTR.ps1.txt - right click and save.

You will need to supply the -DnsServer parameter.

You can also tack on the -Verbose parameter for verbose output (this will also cause verbose output from the DnsShell module to show up).

Script Code

[CmdletBinding()]
param([Parameter(Mandatory=$true)][string] $DnsServer)

# Copyright 2014, Svendsen Tech
# All rights reserved.
# Joakim Borger Svendsen
# 2014-08-28

Import-Module .\DnsShell # this has to exist ( http://dnsshell.codeplex.com/ )

$Zones = Get-DnsZone -Server $DnsServer $ReverseZones = $Zones | Where-Object { $_.ZoneName -like '*.arpa' } | Select-Object -ExpandProperty ZoneName # Example zone: # $ReverseZones = @('12.10.in-addr.arpa') $Dupes = @(foreach ($z in $ReverseZones) { Write-Verbose -Message "Processing zone: $z" $Records = Get-DnsRecord -ServerName $DnsServer -ZoneName $z -RecordType PTR $Records | ForEach-Object -Begin { $IpHash = @{} } -Process { $TempArray = $_.Name -replace '\.in-addr\.arpa$' -split '\.' $Ip = ($TempArray[-1..-($TempArray.Count)]) -join '.' if (-not $IpHash.ContainsKey($Ip)) { # New PTR. The Name property is the PTR. Create one-element array. $IpHash.$Ip = @($_.HostName) } else { # Duplicate/alias PTR, add to array. $IpHash.$Ip += $_.HostName } } $Duplicates = $IpHash.GetEnumerator() | Where-Object { $_.Value.Count -gt 1 } $Duplicates | ForEach-Object { New-Object psobject -Property @{ IP = $_.Name Duplicates = $_.Value -join '; ' } } }) # Display in console. $Dupes | Select IP, Duplicates | Format-Table -AutoSize # Export CSV file (if any dupes found). if ($Dupes.Count) { Write-Host -Fore Green 'Exporting CSV file PTRdupes.csv' $Dupes | Select IP, Duplicates | Export-Csv -Encoding UTF8 -NoTypeInformation -Path PTRdupes.csv -Delimiter ';' }

Another Version That's not Necessarily Dependent on DnsShell

NB! This code below needs to be edited in order to work. Here's an example of a version of the duplicate DNS PTR script that can be adapted to not use DnsShell, if you can somehow get the zones into a file/array. The hard work has been taken care of with dnscmd.exe and parsing its output. This version also has some more detail than the one purely using DnsShell above, with the differentiation between host name and aliases. This version emits objects to the pipeline, so you will probably want to do this (after editing it to fit your environment):
> $Var = .\Get-DupePTR.ps1
...
> $Var | Format-Table # or format-list, export-csv, or whatever sensible you want to do

Download (alternative version)

Get-DupePTR-dnscmd.ps1.txt - right click and download.

Script Code (alternative version)

Adding this code in case it's useful for someone.
[CmdletBinding()]
param()
# Copyright (C) 2014, Svendsen Tech. All rights reserved.
# Joakim Borger Svendsen
# 2014-08-15
# edited: 2014-11-08

$DnsServer = 'your.dns.server'

# This uses DnsShell to get the zones, but you can edit this to read # zones from a file, or whatever, to avoid DnsShell. # It uses dnscmd.exe below and parses its output, and then uses the # (apparently obsolete) [Net.Dns] class' GetHostByAddress() method # to look up the IP #### #### Zones must be in the form 58.10.in-addr.arpa (for 10.58.0.0/16). #### Import-Module .\DnsShell # this has to exist ( http://dnsshell.codeplex.com/ ) $Zones = Get-DnsZone -Server $DnsServer $ReverseZones = $Zones | Where { $_.ZoneName -like '*.arpa' } | Select -ExpandProperty ZoneName # @('58.10.in-addr.arpa') # = foreach ($z in $ReverseZones) { Write-Host -Fore Green "Processing zone: $z" -NoNewline $Records = dnscmd.exe $DnsServer /ZonePrint $z # Get all records and parse them looking for duplicates below. #Write-Host -Fore Yellow " -- Num lines:" $Records.Count $Records | ForEach-Object -Begin { $IpHash = @{}; $Ctr = 0 } ` -Process { if ($_ -match '^([\d.]+)\s+.*PTR\s+(\S+)\.$') { $IpEndReversed = $matches[1] #Write-Verbose $IpEndReversed $Ctr++ Start-Sleep -Milliseconds 25 $TempArray = $z -replace '\.in-addr\.arpa$' -split '\.' $IpStart = ($TempArray[-1..-($TempArray.Count)]) -join '.' $TempArray = $IpEndReversed -split '\.' $IpEnd = ($TempArray[-1..-($TempArray.Count)]) -join '.' #Write-Verbose $IpEnd $Ip = "$IpStart.$IpEnd" #Write-Verbose "Looking up $Ip..." $ErrorActionPreference = 'Stop' try { $Dns = [Net.Dns]::GetHostByAddress($Ip) # This means we found a duplicate. Send an object down the pipeline. if ($Dns.Aliases -match '\S') { New-Object psobject -Property @{ IP = $Ip HostName = $Dns.HostName -join ', ' Aliases = $Dns.Aliases -join ', ' Error = $null } } } catch { New-Object psobject -Property @{ IP = $Ip HostName = $null Aliases = $null Error = $_ } } $ErrorActionPreference = 'Continue' } } Write-Host -Fore Yellow " -- Num records:" $Ctr #Write-Verbose "Processed $Ctr PTR records for $z" #Start-Sleep -Seconds 3 }
Windows      Powershell      DNS      Networking          All Categories

Google custom search of this website only

Minimum cookies is the standard setting. This website uses Google Analytics and Google Ads, and these products may set cookies. By continuing to use this website, you accept this.

If you want to reward my efforts