I recently had a requirement to read and change come permissions on DNS records in an AD Integrated zone. I know I can use the MicrosoftDNS_NSType WMI class to read the records, but this isn’t going to give me any access to permissions. I figure that since the zone is AD Integrated, I can just use ADSI. That is correct, but what I didn’t know is how to find the records. You certainly won’t find them with the Users and Computers container, and ADSIEdit wasn’t showing them to me either.
After a little investigation, it turns out that DNS records are stored in a partition of the directory that ADSIEdit doesn’t load by default. Assuming the name of the zone is contoso.com, the path to the partition is as follows:
dc=contoso.com,cn=MicrosoftDns,dc=DomainDnsZones,dc=contoso,dc=com
With that knowledge, you can enumerate the records with the following script:
set objDNS = GetObject("LDAP://dc=contoso.com,cn=Microsoftdns,dc=DomainDnsZones,dc=contoso,dc=com")
For Each objRecord in objDNS
WScript.Echo objRecord.Name
Next
Getting and settings AD permissions through script is a little tricky. You can get a great discussion of it in this article in ScriptCenter. I won’t try to summarize the article – I’ll just give you the scripts and let you figure out the details behind it.
You can format your output however you like, but I always like to prep it for import into Excel or Access so I can do some analysis across the entire dataset. My personal favorite delimiter is the vertical bar (|) since it just doesn’t show up all that often in other data.
To enumerate the DNS records with their trustees and associated rights, in a delimited format ready for import somewhere else, use the following script. I know I’m just echoing to the screen, but either just direct the output to a file or setup and output file and change my wscript.echo’s to objFile.WriteLine’s:
Set objDNS = GetObject("LDAP://dc=bwren.com,cn=Microsoftdns,dc=DomainDnsZones,dc=bwren,dc=com")
For Each objRecord in objDNS
Set objSD = objRecord.Get("ntSecurityDescriptor")
Set objACL = objSD.DiscretionaryACL
wscript.echo "Record|" & _
"Trustee|" & _
"AceFlags|" & _
"AceType|" & _
"Flags|" & _
"ObjectType|" & _
"InheritedObjectType|" & _
"AccessMask"
For Each objACE in objACL
wscript.Echo objRecord.Get("dc") & "|" & _
objACE.Trustee & "|" & _
objACE.AceFlags & "|" & _
objACE.AceType & "|" & _
objACE.Flags & "|" & _
objACE.ObjectType & "|" & _
objACE.InheritedObjectType & "|" & _
objACE.AccessMask
Next
Next
The tricky part is sifting out the Access Mask. The article I reference above has a little discussion on that. I'll add a more detailed explanation and a script example in a few days.