Wednesday, September 28, 2022
HomePowershellDiscovering duplicate DNS entries utilizing PowerShell

Discovering duplicate DNS entries utilizing PowerShell


If you happen to do not wish to set up the complete module with all different 30+ helpful instructions here is the code for this operate:

operate Get-WinDNSRecords {
    <#
    .SYNOPSIS
    Will get all of the DNS data from all of the zones inside a forest

    .DESCRIPTION
    Will get all of the DNS data from all of the zones inside a forest

    .PARAMETER IncludeZone
    Restrict the output of DNS data to particular zones

    .PARAMETER ExcludeZone
    Restrict the output of dNS data to solely zones not within the exclude record

    .PARAMETER IncludeDetails
    Provides extra data resembling creation time, modified time

    .PARAMETER Prettify
    Converts arrays into strings related with comma

    .PARAMETER IncludeDNSRecords
    Embody full DNS data simply in case one want to additional course of them

    .PARAMETER AsHashtable
    Outputs the outcomes as a hashtable as an alternative of an array

    .EXAMPLE
    Get-WinDNSRecords -Prettify -IncludeDetails | Format-Desk

    .EXAMPLE
    $Output = Get-WinDNSRecords -Prettify -IncludeDetails -Verbose
    $Output.Rely
    $Output | Type-Object -Property Rely -Descending | Choose-Object -First 30 | Format-Desk

    .NOTES
    Basic notes
    #>
    [cmdletbinding()]
    param(
        [string[]] $IncludeZone,
        [string[]] $ExcludeZone,
        [switch] $IncludeDetails,
        [switch] $Prettify,
        [switch] $IncludeDNSRecords,
        [switch] $AsHashtable
    )
    $DNSRecordsCached = [ordered] @{}
    $DNSRecordsPerZone = [ordered] @{}
    $ADRecordsPerZone = [ordered] @{}

    attempt {
        $oRootDSE = Get-ADRootDSE -ErrorAction Cease
    } catch {
        Write-Warning -Message "Get-WinDNSRecords - Couldn't get the basis DSE. Be sure you're logged in to machine with Lively Listing RSAT instruments put in, and there is connecitivity to the area. Error: $($_.Exception.Message)"
        return
    }
    $ADServer = ($oRootDSE.dnsHostName)
    $Exclusions="DomainDnsZones", 'ForestDnsZones', '@'
    $DNS = Get-DnsServerZone -ComputerName $ADServer
    [Array] $ZonesToProcess = foreach ($Zone in $DNS) {
        if ($Zone.ZoneType -eq 'Main' -and $Zone.IsDsIntegrated -eq $true -and $Zone.IsReverseLookupZone -eq $false) {
            if ($Zone.ZoneName -notlike "*_*" -and $Zone.ZoneName -ne 'TrustAnchors') {
                if ($IncludeZone -and $IncludeZone -notcontains $Zone.ZoneName) {
                    proceed
                }
                if ($ExcludeZone -and $ExcludeZone -contains $Zone.ZoneName) {
                    proceed
                }
                $Zone
            }
        }
    }

    foreach ($Zone in $ZonesToProcess) {
        Write-Verbose -Message "Get-WinDNSRecords - Processing zone for DNS data: $($Zone.ZoneName)"
        $DNSRecordsPerZone[$Zone.ZoneName] = Get-DnsServerResourceRecord -ComputerName $ADServer -ZoneName $Zone.ZoneName -RRType A
    }
    if ($IncludeDetails) {
        $Filter = { (Title -notlike "@" -and Title -notlike "_*" -and ObjectClass -eq 'dnsNode' -and Title -ne 'ForestDnsZone' -and Title -ne 'DomainDnsZone' ) }
        foreach ($Zone in $ZonesToProcess) {
            $ADRecordsPerZone[$Zone.ZoneName] = [ordered]@{}
            Write-Verbose -Message "Get-WinDNSRecords - Processing zone for AD data: $($Zone.ZoneName)"
            $TempObjects = @(
                if ($Zone.ReplicationScope -eq 'Area') {
                    attempt {
                        Get-ADObject -Server $ADServer -Filter $Filter -SearchBase ("DC=$($Zone.ZoneName),CN=MicrosoftDNS,DC=DomainDnsZones," + $oRootDSE.defaultNamingContext) -Properties CanonicalName, whenChanged, whenCreated, DistinguishedName, ProtectedFromAccidentalDeletion, dNSTombstoned
                    } catch {
                        Write-Warning -Message "Get-WinDNSRecords - Error getting AD data for DomainDnsZones zone: $($Zone.ZoneName). Error: $($_.Exception.Message)"
                    }
                } elseif ($Zone.ReplicationScope -eq 'Forest') {
                    attempt {
                        Get-ADObject -Server $ADServer -Filter $Filter -SearchBase ("DC=$($Zone.ZoneName),CN=MicrosoftDNS,DC=ForestDnsZones," + $oRootDSE.defaultNamingContext) -Properties CanonicalName, whenChanged, whenCreated, DistinguishedName, ProtectedFromAccidentalDeletion, dNSTombstoned
                    } catch {
                        Write-Warning -Message "Get-WinDNSRecords - Error getting AD data for ForestDnsZones zone: $($Zone.ZoneName). Error: $($_.Exception.Message)"
                    }
                } else {
                    Write-Warning -Message "Get-WinDNSRecords - Unknown replication scope: $($Zone.ReplicationScope)"
                }
            )
            foreach ($DNSObject in $TempObjects) {
                $ADRecordsPerZone[$Zone.ZoneName][$DNSObject.Name] = $DNSObject
            }
        }
    }
    foreach ($Zone in $DNSRecordsPerZone.PSBase.Keys) {
        foreach ($Report in $DNSRecordsPerZone[$Zone]) {
            if ($Report.HostName -in $Exclusions) {
                proceed
            }
            if (-not $DNSRecordsCached["$($Record.HostName).$($Zone)"]) {
                $DNSRecordsCached["$($Record.HostName).$($Zone)"] = [ordered] @{
                    'HostName' = $Report.HostName
                    'Zone'     = $Zone
                    #'RecordType' = $Report.RecordType
                    RecordIP   = [System.Collections.Generic.List[Object]]::new()
                    Varieties      = [System.Collections.Generic.List[Object]]::new()
                    Timestamps = [System.Collections.Generic.List[Object]]::new()
                    Rely      = 0
                }
                if ($ADRecordsPerZone.Keys.Rely -gt 0) {
                    $DNSRecordsCached["$($Record.HostName).$($Zone)"].WhenCreated = $ADRecordsPerZone[$Zone][$Record.HostName].whenCreated
                    $DNSRecordsCached["$($Record.HostName).$($Zone)"].WhenChanged = $ADRecordsPerZone[$Zone][$Record.HostName].whenChanged
                }
                if ($IncludeDNSRecords) {
                    $DNSRecordsCached["$($Record.HostName).$($Zone)"].Checklist = [System.Collections.Generic.List[Object]]::new()
                }
            }
            if ($IncludeDNSRecords) {
                $DNSRecordsCached["$($Record.HostName).$($Zone)"].Checklist.Add($Report)
            }
            if ($null -ne $Report.TimeStamp) {
                $DNSRecordsCached["$($Record.HostName).$($Zone)"].Timestamps.Add($Report.TimeStamp)
            } else {
                $DNSRecordsCached["$($Record.HostName).$($Zone)"].Timestamps.Add("Not obtainable")
            }
            $DNSRecordsCached["$($Record.HostName).$($Zone)"].RecordIP.Add($Report.RecordData.IPv4Address)
            if ($Null -ne $Report.Timestamp) {
                $DNSRecordsCached["$($Record.HostName).$($Zone)"].Varieties.Add('Dynamic')
            } else {
                $DNSRecordsCached["$($Record.HostName).$($Zone)"].Varieties.Add('Static')
            }
            $DNSRecordsCached["$($Record.HostName).$($Zone)"] = [PSCustomObject] $DNSRecordsCached["$($Record.HostName).$($Zone)"]

        }
    }
    foreach ($DNS in $DNSRecordsCached.PSBase.Keys) {
        $DNSRecordsCached[$DNS].Rely = $DNSRecordsCached[$DNS].RecordIP.Rely
        if ($Prettify) {
            $DNSRecordsCached[$DNS].Varieties = $DNSRecordsCached[$DNS].Varieties -join ", "
            $DNSRecordsCached[$DNS].RecordIP = $DNSRecordsCached[$DNS].RecordIP -join ", "
            $DNSRecordsCached[$DNS].Timestamps = $DNSRecordsCached[$DNS].Timestamps -join ", "
        }
    }
    if ($AsHashtable) {
        $DNSRecordsCached
    } else {
        $DNSRecordsCached.Values
    }
}
RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments