Tuesday, August 10, 2010

Finding the distinguishedName of an AD integrated DNS zone

As a precursor to some work I want to do for standard users to be able to create DNS records in AD integrated zones, I threw together some started code to find the actual location of a DNS zone. If you read my previous post looking at DNS without the DNS protocol, I mentioned the various places zones can be located. When you have more than one domain in a forest, this increases the number of possible places to look. This sample code is a basic starter for looking at anything outside of specialized application partitions, to find a specified zone inside the current forest.

#Searches different paritions for the distinguished name of a dns zone
#V1.0 Aug 2010. Checks the forest dns, domain dns and legacy domain dns locations for the existence of a zone
#and returns the distinguished name of all results.
# Future work possibilities. Looking for application partitions. Working with reverse zones in a way that does
# more of a wildcard search to get a better match when the network ID is unknown or scope of the reverse zone is unknown.
#Search capability for subzones that are in the same parent zone
# object. In AD these just show up as part of the record's Name attribute..recordname.subzone

#note, some partitions may not allow authenticated users read access to view the base cn=microsoftDNS containers
#but opening the parent container and doing a subtree search for the zone bypasses this restriction.

$zonename = $args[0]

$forest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
$mytopleveldomain = $forest.schema.name
$mytopleveldomain = $mytopleveldomain.substring($mytopleveldomain.indexof("DC="))

$Arrmyresults = @()

function search-dns-partition($partion, $domainDN, $zonename) {
$de = new-object DirectoryServices.DirectoryEntry("LDAP://" + $partition + $domaindn)
$ds = new-object DirectoryServices.DirectorySearcher($de)
$ds.filter = "(&(objectclass=dnszone)(name=" + $zonename + "))"
$fu = $ds.findone()
if ($fu -ne $null) {
return $fu.properties.distinguishedname
} else { return $null }

function dns-to-dn ([string]$dnsname) {
#may 09

#this is a helper function which will convert a dns name to a distinguished name dc=
#type of result by breaking off each piece of the dns name to become a DC entry

$domainDNnamearr = $dnsname.split(".")
$domainDNname = ""

foreach ($component in $domainDNnamearr) {
$domainDNname = $domainDNname + "DC=" + $component + ","
$domainDNnamearr = $null

#remove trailing , off
$domainDNname = $domainDNname.substring(0,$domainDNname.length -1)
return $domainDNname


#check domain and domain legacy partitions
foreach ($dom in $forest.domains) {
foreach ($partition in ("cn=System,", "dc=domaindnszones,")) {
$domainDNval = dns-to-dn $dom.name
$myresult = search-dns-partition $partition $domainDnVal $zonename
if ($myresult -ne $null) {
$Arrmyresults += $myresult

#Check forest partition
$myresult = search-dns-partition "dc=forestdnszones" $mytopleveldomain $zonename
if ($myresult -ne $null) {
$Arrmyresults += $myresult

return $arrmyresults

No comments:

Post a Comment