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.
#get-dnspartition
#
#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