Last active
August 15, 2025 22:03
-
-
Save jschell/6e469dc5237408172af6faf73b227ac8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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