Skip to content

Instantly share code, notes, and snippets.

@jschell
Last active August 15, 2025 22:03
Show Gist options
  • Select an option

  • Save jschell/6e469dc5237408172af6faf73b227ac8 to your computer and use it in GitHub Desktop.

Select an option

Save jschell/6e469dc5237408172af6faf73b227ac8 to your computer and use it in GitHub Desktop.
function find-staleDNSDomainRecord
{
<#
2017-05-01::0.1.1
- fixed logic
- check DC addr (vs trying to resolve reverse entry)
- match _whole_ word, not partial set, so that if address are same until last octet - x.x.x.1, x.x.x.11, x.x.x.12 - only the full _exact_ match will be returned
- add try/catch for domain lookup in Begin (no need to check the rest if the name doesn't respond on ADWS)
- changed stale entry value to var set in Begin, no more missed matches after changing the string formatting
- if using 'StaleRecordsOnly' switch, array will be returned with the stale addresses only (rather than PsObject of name and ipAddress)
2017-04-28::0.1.0
- inital create
#>
[CmdletBinding()]
Param
(
$Domain = $env:UserDNSDomain,
[ValidateSet('A','AAAA','All')]
$AddressType = 'All',
[Switch]
$StaleRecordsOnly
)
Begin
{
$staleRecordString = '!--STALE ENTRY--!'
Try
{
$targetPDC = (Get-ADDomain -Server $Domain).pdcEmulator
}
Catch
{
Write-Error $_
Break;
}
$domainControllerHostnames = @(Get-ADDomainController -Filter * -Server $Domain |
Select-Object -ExpandProperty Hostname | Sort-Object )
$currentEntries = Resolve-DnsName -Name $Domain -Server $targetPDC
$current_v4 = $currentEntries | Where-Object {$_.Type -eq 'A'} |
Select-Object -ExpandProperty IpAddress
$current_v6 = $currentEntries | Where-Object {$_.Type -eq 'AAAA'} |
Select-Object -ExpandProperty IpAddress
$resolvedAddress = @()
$currentDomainControllerAddr = @()
foreach( $dc in $domainControllerHostnames )
{
$dcAddr = Resolve-DnsName -Name $dc -Server $targetPDC -ErrorAction SilentlyContinue
$dcV4 = ($dcAddr | Where-Object {$_.Type -eq 'A'}).IpAddress
$dcV6 = ($dcAddr | Where-Object {$_.Type -eq 'AAAA'}).IpAddress
$dcIpDetail = New-Object -TypeName PsObject -Property ([ordered]@{
ComputerName = $dc
IpAddress = @(
$dcV4
$dcV6
)
})
$currentDomainControllerAddr += @( $dcIpDetail )
}
}
Process
{
Switch( $AddressType )
{
'A' { $AddressList = @( $current_v4 ) }
'AAAA' { $AddressList = @( $current_v6 ) }
'All'
{
$AddressList = @( $current_v4 )
$AddressList += @( $current_v6 )
}
}
foreach( $entry in $AddressList )
{
$queryResult = New-Object -TypeName PsObject -Property ([ordered]@{
ComputerName = $null
IpAddress = $entry
})
if( $currentDomainControllerAddr.IpAddress -match $entry)
{
$queryResult.ComputerName = ($currentDomainControllerAddr |
Where-Object {$_.IpAddress -match "$($entry)\b" }).computername
}
else
{
$queryResult.ComputerName = $staleRecordString
}
$resolvedAddress += @( $queryResult )
}
}
End
{
$resolvedAddress = $resolvedAddress | Sort-Object -Property ComputerName
if($StaleRecordsOnly)
{
$resolvedAddress = $resolvedAddress |
Where-Object {$_.ComputerName -eq $staleRecordString} |
Select-Object -ExpandProperty IpAddress
}
$resolvedAddress
}
}
function Find-StaleDNSSrvGCEntries
{
<#
# globalCatalog _gc._tcp. DnsForestName gc._.msdcs. DnsForestName
#>
[CmdletBinding()]
Param
(
$Domain = $env:UserDNSDomain,
[Switch]
$StaleRecordsOnly
)
Begin
{
Try
{
$targetPDC = (Get-ADDomain -Server $Domain).pdcEmulator
$domainData = Get-ADDomain -Server $targetPDC
}
Catch
{
Write-Error $_
Break;
}
$forestName = $domainData.Forest
$domainsToResolve = (Get-ADForest -Server $targetPDC).domains
$domainControllerHostnames = @()
foreach( $domain in $domainsToResolve)
{
$domainControllerHostnames += @(Get-ADDomainController -Filter * -Server $domain |
Select-Object -ExpandProperty Hostname | Sort-Object )
}
$resolvedRecords = @()
$currentGcSrvRaw = Resolve-DnsName -Name _gc._tcp.$($forestName) -Server $targetPDC -Type SRV |
Where-Object {$_.section -eq 'Answer'}
$currentGcSrvUnique = $currentGcSrvRaw.NameTarget.ToUpper() | Select-Object -Unique | Sort-Object
$currentGcSrv = @()
foreach($srv in $currentGcSrvUnique)
{
$currentGcSrv += $currentGcSrvRaw | where {$_.NameTarget -match $srv}
}
}
Process
{
$gcSRV = $currentGcSrv
foreach( $srvRecord in $gcSRV )
{
$queryResult = New-Object -TypeName PsObject -Property ([ordered]@{
DomainController = $null
SRVName = $($srvRecord.Name)
NameTarget = $($srvRecord.NameTarget)
Priority = $($srvRecord.Priority)
Weight = $($srvRecord.Weight)
IsCurrent = $False
})
if( $domainControllerHostnames -match $srvRecord.NameTarget )
{
$queryResult.DomainController = $srvRecord.NameTarget
$queryResult.IsCurrent = $True
}
$resolvedRecords += @($queryResult)
}
}
End
{
$resolvedRecords = $resolvedRecords | Sort-Object -Property IsCurrent, Priority, Weight, DomainController
if($StaleRecordsOnly)
{
$resolvedRecords = $resolvedRecords | Where-Object {$_.IsCurrent -eq $False} | Sort-Object NameTarget
}
$resolvedRecords
}
}
function Find-StaleDNSSrvKerberosEntries
{
<#
# kerberos _kerberos._tcp DnsDomainName _kerberos._tcp.dc._msdcs. DnsDomainName
#>
[CmdletBinding()]
Param
(
$Domain = $env:UserDNSDomain,
[Switch]
$StaleRecordsOnly
)
Begin
{
Try
{
$targetPDC = (Get-ADDomain -Server $Domain).pdcEmulator
$domainData = Get-ADDomain -Server $targetPDC
}
Catch
{
Write-Error $_
Break;
}
$resolvedRecords = @()
$domainControllerHostnames = @(Get-ADDomainController -Filter * -Server $Domain |
Select-Object -ExpandProperty Hostname | Sort-Object )
$currentKrbSRV = Resolve-DnsName -Name _kerberos._tcp.$($domainData.DnsRoot) -Server $targetPDC -Type SRV |
Where-Object {$_.section -eq 'Answer'}
$currentKrbMsdcsSRV = Resolve-DnsName -Name _kerberos._tcp.dc._msdcs.$($domainData.DnsRoot) -Server $targetPDC -Type SRV |
Where-Object {$_.section -eq 'Answer'}
}
Process
{
$krbSRV = $currentKrbSRV
$krbSRV += $currentKrbMsdcsSRV
foreach( $srvRecord in $krbSRV )
{
$queryResult = New-Object -TypeName PsObject -Property ([ordered]@{
DomainController = $null
SRVName = $($srvRecord.Name)
NameTarget = $($srvRecord.NameTarget)
Priority = $($srvRecord.Priority)
Weight = $($srvRecord.Weight)
IsCurrent = $False
})
if( $domainControllerHostnames -match $srvRecord.NameTarget )
{
$queryResult.DomainController = $srvRecord.NameTarget
$queryResult.IsCurrent = $True
}
$resolvedRecords += @($queryResult)
}
}
End
{
$resolvedRecords = $resolvedRecords | Sort-Object -Property IsCurrent, Priority, Weight, DomainController
if($StaleRecordsOnly)
{
$resolvedRecords = $resolvedRecords | Where-Object {$_.IsCurrent -eq $False}
}
$resolvedRecords
}
}
function Find-StaleDNSSrvLdapEntries
{
<#
# ldap _ldap._tcp. DnsDomainName _ldap._tcp.dc._msdcs. DnsDomainName
#>
[CmdletBinding()]
Param
(
$Domain = $env:UserDNSDomain,
[Switch]
$StaleRecordsOnly
)
Begin
{
Try
{
$targetPDC = (Get-ADDomain -Server $Domain).pdcEmulator
$domainData = Get-ADDomain -Server $targetPDC
}
Catch
{
Write-Error $_
Break;
}
$resolvedRecords = @()
$domainControllerHostnames = @(Get-ADDomainController -Filter * -Server $Domain |
Select-Object -ExpandProperty Hostname | Sort-Object )
$currentLdapSRV = Resolve-DnsName -Name _ldap._tcp.$($domainData.DnsRoot) -Server $targetPDC -Type SRV |
Where-Object {$_.section -eq 'Answer'}
$currentLdapMsdcsSRV = Resolve-DnsName -Name _ldap._tcp.dc._msdcs.$($domainData.DnsRoot) -Server $targetPDC -Type SRV |
Where-Object {$_.section -eq 'Answer'}
}
Process
{
$ldapSRV = $currentLdapSRV
$ldapSRV += $currentLdapMsdcsSRV
foreach( $srvRecord in $ldapSRV )
{
$queryResult = New-Object -TypeName PsObject -Property ([ordered]@{
DomainController = $null
SRVName = $($srvRecord.Name)
NameTarget = $($srvRecord.NameTarget)
Priority = $($srvRecord.Priority)
Weight = $($srvRecord.Weight)
IsCurrent = $False
})
if( $domainControllerHostnames -match $srvRecord.NameTarget )
{
$queryResult.DomainController = $srvRecord.NameTarget
$queryResult.IsCurrent = $True
}
$resolvedRecords += @($queryResult)
}
}
End
{
$resolvedRecords = $resolvedRecords | Sort-Object -Property IsCurrent, Priority, Weight, DomainController
if($StaleRecordsOnly)
{
$resolvedRecords = $resolvedRecords | Where-Object {$_.IsCurrent -eq $False}
}
$resolvedRecords
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment