When I read this I was like huh?
I admit to not even knowing that proxyAddresses was in the
default schema, been too long since I have seen an untainted schema. I thought
Exchange put it there. Exchange must simply add proxyAddresses to the
PAS and tell it to be preserved through tombstoning.
Exchange would have serious issues I think if
proxyAddresses wasn't in the PAS.
joe
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Coleman, Hunter
Sent: Thursday, December 30, 2004 10:26 AM
To: ActiveDir@mail.activedir.org
Subject: RE: [ActiveDir] How to find duplicate proxy address in Active Directory
IIRC, proxyAddresses isn't in the default GC attribute set,
so in a multi-domain forest you may be missing dupes. In that case, you
could either include proxyAddresses in the partial attribute set or loop through
a list of the domains and query each domain.
Hunter
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of joe
Sent: Thursday, December 30, 2004 7:49 AM
To: ActiveDir@mail.activedir.org
Subject: RE: [ActiveDir] How to find duplicate proxy address in Active Directory
:o)
Good job Michael. Honestly I am sure quite a few people are
happy and thinking, god I hate that perl crap[1].... You have offered an
alternative. ;o)
As for your filter.... your filter is fine if
the audit is only against users. If you also want to check the addresses of
groups and contacts as well then I have found just using proxyAddresses is fine
because it is indexed. If you have exchange enabled contacts and groups,
probably worth adding them to the check since they could dupe up your addresses,
especially contacts. I have seen a couple of occasions where people move someone
from being a user to being a contact and you get proxyAddress dupes there on
secondaries.
Also you should probably enable paging. I expect many
of the folks who would like to use this and most likely have programs/systems
that would introduce the dupes will have more than 1000 exchange enabled
objects. That is kind of hidden in my solution as adfind always automatically
pages. It also automatically does ranging but I wouldn't expect either that
someone would have more than 1000 addresses listed in a proxyAddresses
attribute. I do not recall off the top of my head if ADO will do the ranging
automatically.
Another suggestion I would make is simply for perf.
Possibly have a second dictionary for the duped items. That way you can get away
from the instr which is fairly expensive especially if you have big strings
(lots of addresses per DN) or you have lots of addresses. I could gain some
additional perf that way as well but checking an int isn't very expensive, if
there were tens of thousands of addresses though, you would most likely feel a
difference in the run speed even just checking ints.
Finally, I have found I like dumping the data ahead of time
and then parsing it out. This is strictly from working on very large directories
where I have experienced servers dropping connections with "Server Unavailable"
midway through. That way you don't process x amount and it bombs and you go WTF,
you just restart the dump.
I am actually suprised how small the vbscript code is,
would have expected more lines of code; well done.
joe
[1] To those I say, wipe the drool off your chin son...
j/k
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Michael B. Smith
Sent: Wednesday, December 29, 2004 11:20 PM
To: ActiveDir@mail.activedir.org
Subject: RE: [ActiveDir] How to find duplicate proxy address in Active Directory
Not that I didn't have anything else to do for the last 45
minutes, but I needed a break. I'm sure Joe won't like my filter, he never does.
:-) :-)
strDomainDN = "dc=brnets,dc=local"
strBase = "<GC://" & strDomainDN & ">;"
strBase = "<GC://" & strDomainDN & ">;"
strFilter =
"(&(objectclass=user)(objectcategory=person)(proxyAddresses=*));"
strAttrs = "name,adspath,proxyaddresses;"
strScope = "subtree"
strAttrs = "name,adspath,proxyaddresses;"
strScope = "subtree"
Set objDIC =
CreateObject("Scripting.Dictionary")
set objConn =
CreateObject("ADODB.Connection")
objConn.Provider = "ADsDSOObject"
objConn.Open "Active Directory Provider"
set objRS = objConn.Execute(strBase & strFilter & strAttrs & strScope)
objRS.MoveFirst
objConn.Provider = "ADsDSOObject"
objConn.Open "Active Directory Provider"
set objRS = objConn.Execute(strBase & strFilter & strAttrs & strScope)
objRS.MoveFirst
iCount = 0
while Not objRS.EOF
'Wscript.Echo "name = " & objRS.Fields(0).Value
'wscript.echo "adspath = " & objRS.Fields(1).Value
proxyaddresses = objRS.Fields(2)
for each proxyaddress in proxyaddresses
proxyaddress = LCase (proxyaddress)
If objDic.Exists (proxyaddress) Then
objDic.Item (proxyAddress) = objDic.Item (proxyAddress) & "|" & objRS.Fields(1).Value
wscript.echo "Dup: " & objDic.Item (proxyAddress)
iCount = iCount + 1
Else
objDic.Add proxyAddress, objRS.Fields(1).value
End If
next
'wscript.echo
objRS.MoveNext
wend
'Wscript.Echo "name = " & objRS.Fields(0).Value
'wscript.echo "adspath = " & objRS.Fields(1).Value
proxyaddresses = objRS.Fields(2)
for each proxyaddress in proxyaddresses
proxyaddress = LCase (proxyaddress)
If objDic.Exists (proxyaddress) Then
objDic.Item (proxyAddress) = objDic.Item (proxyAddress) & "|" & objRS.Fields(1).Value
wscript.echo "Dup: " & objDic.Item (proxyAddress)
iCount = iCount + 1
Else
objDic.Add proxyAddress, objRS.Fields(1).value
End If
next
'wscript.echo
objRS.MoveNext
wend
wscript.echo "Total unique addresses found: " &
objDic.Count
If iCount = 0 Then
Wscript.Echo "No dups found"
Else
Dim objArr, objIt, strVals
Wscript.Echo "No dups found"
Else
Dim objArr, objIt, strVals
objArr = objDic.Keys
For Each objIt in objArr
strVals = objDic.Item (objIt)
If Instr (strVals, "|") > 0 Then
Dim arrNames, strName
For Each objIt in objArr
strVals = objDic.Item (objIt)
If Instr (strVals, "|") > 0 Then
Dim arrNames, strName
arrNames = Split (strVals,
"|")
wscript.echo objIt
For each strName in arrNames
wscript.echo vbTab & strName
Next
End If
Next
End If
wscript.echo objIt
For each strName in arrNames
wscript.echo vbTab & strName
Next
End If
Next
End If
wscript.quit 0
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of joe
Sent: Wednesday, December 29, 2004 5:59 PM
To: ActiveDir@mail.activedir.org
Subject: RE: [ActiveDir] How to find duplicate proxy address in Active Directory
Hmm I think I previously posted a script that does this to
the list, at least that basic functionality.I can't find it though so here is a
basic one again. We have definitely discussed this a couple of
times previously though.
It is pretty simple functionality, simply form a query of
base: ""
port: global catalog aka 3268
filter: proxyaddresses=*
then parse through all of the returned proxyaddresses and
slap them into a hash with the proxy address normalized as the key. If the hash
entry exists, tack on the new DN to the value. At the end chase through all hash
entries looking for entries with multiple values. In perl I recommend using a
hash value of an array to make it easiest.
The adfind ldap query dumped to a testpa.txt file would
look like
adfind -gc -b "" -f proxyaddresses=* proxyaddresses >
testpa.txt
Of course for more advanced checking, you probably also
want to make sure legacyExchangeDNs don't dupe any X500 proxyaddresses because
that would be a bad dupe as well. I will leave that as an exercise for the
class.
Anyway, dump the above command to a text file. Use ADCSV to
convert to a CSV file. Tell ADCSV to use # to separate multivalue attribs
because semicolon's won't work for this case.
adcsv /infile:testpa.txt /mvdelim:#
Should give you a text file like:
DN;proxyAddresses;
"CN=$jricha34,CN=Users,DC=joe,DC=com";"SMTP:[EMAIL PROTECTED];X400:c=US;a= ;p=joeware;o=Exchange;s=?jricha34;";
"CN=Public Folder Store (2K3EXC01),CN=SG1,CN=InformationStore,CN=2K3EXC01,CN=Servers,CN=First Administrative Group,CN=Administrative Groups,CN=joeware,CN=Microsoft Exchange,CN=Serv
ices,CN=Configuration,DC=joe,DC=com";"smtp:[EMAIL PROTECTED];smtp:[EMAIL PROTECTED];SMTP:[EMAIL PROTECTED];X400:c=US;a= ;p=joeware;o=Exchange;s=2K3EXC01-IS;";
"CN=Microsoft System Attendant,CN=2K3EXC01,CN=Servers,CN=First Administrative Group,CN=Administrative Groups,CN=joeware,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=joe,DC
=com";"smtp:[EMAIL PROTECTED];smtp:[EMAIL PROTECTED];SMTP:[EMAIL PROTECTED];X400:c=US;a= ;p=joeware;o=Exchange;s=2K3EXC01-SA;";
"CN=postmaster,OU=MailUsers,OU=joeware2,OU=Exchange,DC=joe,DC=com";"smtp:[EMAIL PROTECTED];SMTP:[EMAIL PROTECTED];smtp:[EMAIL PROTECTED];X400:c=US;a= ;p=joeware;o=Exchange;
s=postmaster;";
"CN=$jricha34,CN=Users,DC=joe,DC=com";"SMTP:[EMAIL PROTECTED];X400:c=US;a= ;p=joeware;o=Exchange;s=?jricha34;";
"CN=Public Folder Store (2K3EXC01),CN=SG1,CN=InformationStore,CN=2K3EXC01,CN=Servers,CN=First Administrative Group,CN=Administrative Groups,CN=joeware,CN=Microsoft Exchange,CN=Serv
ices,CN=Configuration,DC=joe,DC=com";"smtp:[EMAIL PROTECTED];smtp:[EMAIL PROTECTED];SMTP:[EMAIL PROTECTED];X400:c=US;a= ;p=joeware;o=Exchange;s=2K3EXC01-IS;";
"CN=Microsoft System Attendant,CN=2K3EXC01,CN=Servers,CN=First Administrative Group,CN=Administrative Groups,CN=joeware,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=joe,DC
=com";"smtp:[EMAIL PROTECTED];smtp:[EMAIL PROTECTED];SMTP:[EMAIL PROTECTED];X400:c=US;a= ;p=joeware;o=Exchange;s=2K3EXC01-SA;";
"CN=postmaster,OU=MailUsers,OU=joeware2,OU=Exchange,DC=joe,DC=com";"smtp:[EMAIL PROTECTED];SMTP:[EMAIL PROTECTED];smtp:[EMAIL PROTECTED];X400:c=US;a= ;p=joeware;o=Exchange;
s=postmaster;";
<SNIP>
Now build a perl script that looks through all lines of the
file and shoves the values into the hash and then outputs the hash entries that
have multiple values. Here would be a basic script to do it.
$pahash=();
foreach $thisline (<>)
{
($dn,$pa)=($thisline=~/"(.+?)";"(.+)"/);
map {$pahash{lc($_)}[++$pahash{lc($_)}[0]]=$dn} split(/#/,$pa);
}
foreach $thisline (<>)
{
($dn,$pa)=($thisline=~/"(.+?)";"(.+)"/);
map {$pahash{lc($_)}[++$pahash{lc($_)}[0]]=$dn} split(/#/,$pa);
}
foreach $thiskey (sort keys %pahash)
{
next unless $pahash{$thiskey}[0]>1;
print "Duped: $thiskey\n";
for $thisentry (1..$pahash{$thiskey}[0]) {print " ".$pahash{$thiskey}[$thisentry]."\n"};
}
{
next unless $pahash{$thiskey}[0]>1;
print "Duped: $thiskey\n";
for $thisentry (1..$pahash{$thiskey}[0]) {print " ".$pahash{$thiskey}[$thisentry]."\n"};
}
I'll leave it to Brian or Deji or one of the other vbscript
guys to come up with the equiv vbscript code.
Once you get to here, the next step is inevitably to start
asserting that the addresses are valid in format and characters and labels, etc.
That is when it starts to get tough.
joe
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Manjeet
Sent: Wednesday, December 29, 2004 4:02 PM
To: ActiveDir@mail.activedir.org
Subject: [ActiveDir] How to find duplicate proxy address in Active Directory
All,
I am facing a lots of problem due to duplicate proxy address in active
directory. Some of my user's mails are bouncing back due to this. I have tried
Active directory search but no result found. I am looking for a good tool by
which I can search out the duplicate proxy address and delete them.
I was trying dupproxy.exe but its giving error than can not open
LDAP.
Your early help will pe appericiated.
Thank You,
Manjeet
Do you Yahoo!?
Yahoo! Mail - Easier than ever with enhanced search. Learn more.