WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

ADSI
plus

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

Distribution List and Members


Question:

I've been ask to come up with a way to check on distribution list and who's on them as part of our move to a new domain structure, is there a simple way for WinBatch to get a list of all distribution list and they member.

This task need to be done in more than one place and the new domain needs to match the old domain, hopefully without duplication :)

(Windows 2000 (and some old NT 4 box's to be dropped) going to Windows 2003)

Answer:

Check out the ADSI extender. It can get the membership list for both security and distribution groups in an AD domain.

User Reply:

Got this working thanks :)
;Win 32 Network extender
AddExtender("WWWNT34i.DLL")
;---------------------------------------------------------------------------------------------
;Windows ADSI extender
AddExtender("WWADS34I.DLL")
;---------------------------------------------------------------------------------------------
servera = wntServerList("", "", -1)
serverlist = StrReplace(servera, "\\", "")
serverchk = AskItemList("Group Monitor - Which Machine", serverlist, @TAB, @SORTED, @SINGLE)
inifile = "c:\temp\%serverchk%_groups.ini"
pdc = StrReplace(wntServerList("", "", 8), "\", "/")
sAdsiPath = "LDAP:%pdc%" ; 
report = ""

; Find the complete path to the user object.
sUserPath = dsFindPath(sAdsiPath, "cn=*")

For groupno = 1 to ItemCount(sUserPath, @TAB)
userpath = ItemExtract(groupno, sUserPath, @TAB)

If StrIndexNc(userpath, "ou=group", 0, @FWDSCAN) != 0
startpos = StrIndexNc(userpath, "Cn=", 0, @FWDSCAN) + 3
endpos = StrIndexNc(userpath, ",", startpos, @FWDSCAN) - startpos
Group = StrSub(userpath, startpos, endpos)
listtwo = StrLower(dsGetMemGrp(userpath))
listone = StrReplace(StrLower(IniItemizePvt(group, inifile)), "#", "=")

If listtwo == "(none)"
listtwo = ""
numberin = 0
Else
numberin = ItemCount(listtwo, @TAB)
EndIf

newlistone = ""

If listone == "(none)" 
listone = ""
Else
For x = 1 to Itemcount(listone, @TAB)
rgroup = ItemExtract(x, listone, @TAB)
findgroup = ItemLocate(rgroup, listtwo, @TAB)

If findgroup != 0
listtwo = ItemRemove(findgroup, listtwo, @TAB)
Else
newlistone = ItemInsert(rgroup, -1, newlistone, @TAB)
EndIf
Next x

listone = newlistone
drop(newlistone)

Endif

listone = StrReplace(listone, @TAB, StrCat(@CRLF, " "))
listtwo = StrReplace(listtwo, @TAB, StrCat(@CRLF, " "))
grouplen = StrLen(group)
underline = StrFix("=", "=", grouplen)

If listone != ""
report = StrCat(report, group, " (", numberin, ")", @CRLF, underline, @CRLF, "User(s) removed ", @CRLF, " ", listone, @CRLF)

If listtwo != "" 
report = StrCat(report, "User(s) added ", @CRLF, " ", listtwo, @CRLF)
EndIf

Report = StrCat(report, @CRLF)
Else

If listtwo != "" 
report = StrCat(report, group, " (", numberin, ")", @CRLF, underline, @CRLF, "User(s) added ", @CRLF, " ", listtwo, @CRLF, @CRLF)
EndIf
EndIf
EndIf

Next groupno

FilePut("c:\temp\%serverchk%_group_report.txt", report)

scr01Format=`WWWDLGED,6.1`

scr01Caption=`Group Monitor`
scr01X=061
scr01Y=045
scr01Width=368
scr01Height=285
scr01NumControls=003
scr01Procedure=`DEFAULT`
scr01Font=`DEFAULT`
scr01TextColor=`DEFAULT`
scr01Background=`DEFAULT,DEFAULT`
scr01Config=0

scr01001=`003,005,354,248,MULTILINEBOX,Report,"Help",DEFAULT,3,8,"Courier New|6144|40|49","0|0|0",DEFAULT`
scr01002=`303,263,050,012,PUSHBUTTON,DEFAULT,"Save Base Line",1,2,DEFAULT,DEFAULT,DEFAULT,DEFAULT`
scr01003=`007,263,036,012,PUSHBUTTON,DEFAULT,"Report Only",2,1,DEFAULT,DEFAULT,DEFAULT,DEFAULT`

ButtonPushed=Dialog("scr01")

Answer:

A couple of caveats apply to using the NT extender in an AD environment.
  1. The domain object, security/distribution group objects and all user objects must have pre-2000 names assigned to them. If they lack these names then they cannot be seen by the NT extender as it uses Win32 API functions that only work with NT-style domain interfaces. AD objects lacking pre-2000 name values are invisible to those API functions.

  2. The server name specified in the function calls must specify the name of a DC for the domain object which directly contains the specified objects, or the OU containers in which the specified objects are located beneath the domain. Again, this comes as limitation of the Win32 API functions that access NT-style domain information.
The use of the ADSI extender will allow for this information to be obtained from AD w/o being concerned about whether or not pre-2000 naming information has been properly assigned to all of the objects that may need to be accessed when determining group membership regardless of the type of group.

Also, please note that the NT extender cannot distinguish between a security group and a distribution group, and a distribution group cannot be used in assigning permissions and/or ownership to folders, files, shares, printers, etc... Because of this, simply enumerating the global groups in a domain and attempting assign permissions for them on folders & files on NTFS volume could be dangerous since distribution groups & their members may be enumerated even if the group objects themselves are invalid for use as a security principle.


Article ID:   W16308
File Created: 2005:02:18:12:19:44
Last Updated: 2005:02:18:12:19:44