query smtp addresses in AD

C

Clay Calvert

Have a list of many e-mail addresses (accounts) to be imported into
AD. Due to rare circumstances with connectors to legacy systems there
are occasionally orphan e-mail addresses that cause imports to fail,
at least for such accounts.

How can a list of e-mail addresses be queried to see if any of them
already exist? Basically an automated way of Start, Search, For
People, Active Directory, then E-mail.

Thanks

Clay Calvert
(e-mail address removed)
Replace "W" with "L"
 
M

Marty List

Clay Calvert said:
Have a list of many e-mail addresses (accounts) to be imported into
AD. Due to rare circumstances with connectors to legacy systems there
are occasionally orphan e-mail addresses that cause imports to fail,
at least for such accounts.

How can a list of e-mail addresses be queried to see if any of them
already exist? Basically an automated way of Start, Search, For
People, Active Directory, then E-mail.

Thanks

Clay Calvert
(e-mail address removed)
Replace "W" with "L"


This could be done very easily with ADSI and VBS or JavaScript. If that's
an option for you I could write a script that would get you started.
Provide more detail what you mean by "a list of e-mail addresses" and
explain which direction the query is going. Are you looking for addresses
that exist in your list but not AD, or the opposite.
 
C

Clay Calvert

This could be done very easily with ADSI and VBS or JavaScript. If that's
an option for you I could write a script that would get you started.
Provide more detail what you mean by "a list of e-mail addresses" and
explain which direction the query is going. Are you looking for addresses
that exist in your list but not AD, or the opposite.

VBS would be great. The addresses are in a .CSV file as the first
column, but they can be put into their own text file easily.

Looking for addresses in the list that exist in AD, so both. None of
the addresses in the list 'should' be in AD already.

Thank you very much.

Clay Calvert
(e-mail address removed)
Replace "W" with "L"
 
M

Marty List

Clay Calvert said:
VBS would be great. The addresses are in a .CSV file as the first
column, but they can be put into their own text file easily.

Looking for addresses in the list that exist in AD, so both. None of
the addresses in the list 'should' be in AD already.

Thank you very much.

Clay Calvert
(e-mail address removed)
Replace "W" with "L"


Hi Clay,

Attached is a VBS file with the extension renamed, this should get you
started. Near the top of the script you will need to change the domain name
and the name of the file
containing your email addresses.

This script uses ADSI to query AD using an LDAP filter on the mail attribute
of each user account. For best results run it with CSCRIPT.EXE, not
WSCRIPT.EXE.


Marty

PS - The same script is pasted below, but with line wraps it will be ugly:


Option Explicit
On Error Resume Next


Const ADS_PATH = "DC=yourdomain,DC=com"
Const SEARCH_FILE = "C:\Temp\Test.txt"
Const FOR_READING = 1

Dim objFS, objFile
Dim objADOConnection, objADOCommand
Dim intResult, strResult
Dim strNextLine, arrNextLine
Dim strADResult
Dim DebugMode

DebugMode = True


' Open the text file for reading:
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objFile = objFS.OpenTextFile(SEARCH_FILE, FOR_READING, False)
intResult = Err.Number
strResult = Err.Description
If intResult <> 0 Then
WScript.Echo "Failed to open " & SEARCH_FILE & ", error " & CStr(intResult)
& " (" & strResult & ")"
WScript.Quit(intResult)
End If

' Open the ADo connection:
Set objADOConnection = CreateObject("ADODB.Connection")
Set objADOCommand = CreateObject("ADODB.Command")
If Err.Number <> 0 Then
WScript.Echo "Failed to create an ADO connection, check MDAC installation."
WScript.Quit(Err.Number)
End If

' Open the ADSI connection:
objADOConnection.Provider = "ADsDSOObject" ' This is the ADSI OLE-DB
provider name
objADOConnection.Open "Active Directory Provider"
If Err.Number <> 0 Then
WScript.Echo "Failed to open an ADSI connection, check AD client
installation."
WScript.Quit(Err.Number)
End If
Set objADOCommand.ActiveConnection = objADOConnection


strNextLine = objFile.ReadLine
While Err.Number = 0
Trace("strNextLine: [" & strNextLine & "]")
If Trim(strNextLine) <> "" Then
arrNextLine = Split(strNextLine, ",")
strADResult = LookupADAccount(ADS_PATH, "mail", arrNextLine(0))
WScript.Echo arrNextLine(0) & "=" & strADResult
End If
strNextLine = objFile.ReadLine
Wend

objFile.Close
Set objFile = Nothing
Set objFS = Nothing

WScript.Quit(0)


Function LookupADAccount(ByVal strADsPath, ByVal strAttributeName, ByVal
strProperty)
Trace("LookupADAccount(" & strAttributeName & ", " & strProperty & ")")
LookupADAccount = "No match"

Dim objRS
Dim strCommand, strBuffer


If Trim(strADsPath) = "" Then
LookupADAccount = "Failed, invalid LDAP DN."
Exit Function
End If


If Left(UCase(strADsPath), 7) = "LDAP://" Then
strADsPath = Right(strADsPath, Len(strADsPath) - 7)
End If

' Compose the search query.
' See
http://msdn.microsoft.com/library/en-us/netdir/adsi/search_filter_syntax.asp
strCommand = "select name," & strAttributeName & " from 'LDAP://" &
strADsPath & "' WHERE " & _
"objectCategory = 'person' " & _
"AND objectClass='user' " & _
"AND " & strAttributeName & "='" & strProperty & "'"

objADOCommand.CommandText = strCommand

Set objRS = objADOCommand.Execute

' Navigate the record set
While Not objRS.EOF
LookupADAccount = objRS.FIELDS("Name")
objRS.MoveNext
Wend
End Function


Sub Trace(ByVal strMessage)
If DebugMode Then WScript.Echo "DEBUG: " & strMessage
End Sub
 
M

Marty List

Clay Calvert said:
VBS would be great. The addresses are in a .CSV file as the first
column, but they can be put into their own text file easily.

Looking for addresses in the list that exist in AD, so both. None of
the addresses in the list 'should' be in AD already.

Thank you very much.

Clay Calvert
(e-mail address removed)
Replace "W" with "L"


This might be a duplicate, I replied to this earlier with a VBS file
attached, but some newsservers block attachments so I thought I would post
again with it pasted inside.


Hi Clay,

Below is a VBS script, this should get you started. Near the top of the
script you will need to change the domain name and the name of the file
containing your email addresses.

This script uses ADSI to query AD using an LDAP filter on the mail attribute
of each user account. For best results run it with CSCRIPT.EXE, not
WSCRIPT.EXE.


Marty



Watch out for line wraps:


Option Explicit
On Error Resume Next


Const ADS_PATH = "DC=yourdomain,DC=com"
Const SEARCH_FILE = "C:\Temp\Test.txt"
Const FOR_READING = 1

Dim objFS, objFile
Dim objADOConnection, objADOCommand
Dim intResult, strResult
Dim strNextLine, arrNextLine
Dim strADResult
Dim DebugMode

DebugMode = True


' Open the text file for reading:
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objFile = objFS.OpenTextFile(SEARCH_FILE, FOR_READING, False)
intResult = Err.Number
strResult = Err.Description
If intResult <> 0 Then
WScript.Echo "Failed to open " & SEARCH_FILE & ", error " & _
CStr(intResult) & " (" & strResult & ")"
WScript.Quit(intResult)
End If

' Open the ADo connection:
Set objADOConnection = CreateObject("ADODB.Connection")
Set objADOCommand = CreateObject("ADODB.Command")
If Err.Number <> 0 Then
WScript.Echo "Failed to create ADO connection, check MDAC installation."
WScript.Quit(Err.Number)
End If

' Open the ADSI connection:
objADOConnection.Provider = "ADsDSOObject"
objADOConnection.Open "Active Directory Provider"
If Err.Number <> 0 Then
WScript.Echo "Failed to open ADSI connection, check AD client
installation."
WScript.Quit(Err.Number)
End If
Set objADOCommand.ActiveConnection = objADOConnection


strNextLine = objFile.ReadLine
While Err.Number = 0
Trace("strNextLine: [" & strNextLine & "]")
If Trim(strNextLine) <> "" Then
arrNextLine = Split(strNextLine, ",")
strADResult = LookupADAccount(ADS_PATH, "mail", arrNextLine(0))
WScript.Echo arrNextLine(0) & "=" & strADResult
End If
strNextLine = objFile.ReadLine
Wend

objFile.Close
Set objFile = Nothing
Set objFS = Nothing

WScript.Quit(0)


Function LookupADAccount(ByVal strADsPath, ByVal strAttributeName, ByVal
strProperty)
Trace("LookupADAccount(" & strAttributeName & ", " & strProperty & ")")
LookupADAccount = "No match"

Dim objRS
Dim strCommand, strBuffer


If Trim(strADsPath) = "" Then
LookupADAccount = "Failed, invalid LDAP DN."
Exit Function
End If


If Left(UCase(strADsPath), 7) = "LDAP://" Then
strADsPath = Right(strADsPath, Len(strADsPath) - 7)
End If

' Compose the search query. See:

'http://msdn.microsoft.com/library/en-us/netdir/adsi/search_filter_syntax.as
p
strCommand = "select name," & strAttributeName & " from 'LDAP://" & _
strADsPath & "' WHERE " & _
"objectCategory = 'person' " & _
"AND objectClass='user' " & _
"AND " & strAttributeName & "='" & strProperty & "'"

objADOCommand.CommandText = strCommand

Set objRS = objADOCommand.Execute

' Navigate the record set
While Not objRS.EOF
LookupADAccount = objRS.FIELDS("Name")
objRS.MoveNext
Wend
End Function


Sub Trace(ByVal strMessage)
If DebugMode Then WScript.Echo "DEBUG: " & strMessage
End Sub
 
C

Clay Calvert

I appreciate you putting this together to help me out, however there
are two things.

1. I should have been clearer with my meaning of "orphan" e-mail
addresses. These are addresses that don't necessarily have an account
associated with them. They are usually contacts that have been
abandoned.

2. I'm also getting the following error:

"Failed to open an ADSI connection, check AD client installation."

I'm not sure why I'm getting this error. I'm running this from an XP
Pro SP1 machine and other AD tools are working such as: Search.vbs,
Joe's AdFind, and DSquery from the Win2003 admin pack.

I should say they are working, but I haven't figured out how to get
them to answer what I'm looking for. ; )

DSquery looks promising, if I can figure it out.

Thanks again.

Clay Calvert
(e-mail address removed)
Replace "W" with "L"
 
M

Marty List

Clay Calvert said:
I appreciate you putting this together to help me out, however there
are two things.

1. I should have been clearer with my meaning of "orphan" e-mail
addresses. These are addresses that don't necessarily have an account
associated with them. They are usually contacts that have been
abandoned.

2. I'm also getting the following error:

"Failed to open an ADSI connection, check AD client installation."

I'm not sure why I'm getting this error. I'm running this from an XP
Pro SP1 machine and other AD tools are working such as: Search.vbs,
Joe's AdFind, and DSquery from the Win2003 admin pack.

I should say they are working, but I haven't figured out how to get
them to answer what I'm looking for. ; )

DSquery looks promising, if I can figure it out.

Thanks again.

Clay Calvert
(e-mail address removed)
Replace "W" with "L"

I'm not getting your point on #1, I guess I don't understand what you are
trying to accomplish. Try explaining it a different way. You said in a
earlier post that you are "Looking for addresses in the list that exist in
AD". The script loops through each line of the text file and looks for that
email address in AD. If the address is found in AD, it prints out the
account name. If it's not found, it prints "No match".

I don't know why it would fail to open the connection, I've only seen that
happen on NT4 machines. I've run the script on 2 Win2000 machines and one
XP machine. Try running it from a different machine? Try adding some more
error checking, in addition to "Err.Number" try getting the
"Err.Description" and see if that provides a clue.
 
J

Joe Richards [MVP]

If the problem is, give me a list of all email addresses listed in AD and then check to see if any of the ones in a
given list are already in AD and you don't need to know anything else I would

1. Use ADFIND or something else to dump all the email addresses in AD to a text file

adfind -gc -b -f mail=* mail |findstr /i mail:

which should give you output like:
mail: bob
mail: (e-mail address removed)
mail: (e-mail address removed)

2. Write up a little script to parse your list and throw the info into a vb dictionary object or a perl hash

open ifh1,"<emails.txt"
@in=<ifh1>
close ifh1;
chomp ifh1;
foreach (@in)
{
chomp;
$myhash{lc($_)}=1;
}


3. Parse through the generated file from AD and strip off the >mail: and then do a lookup in the hash

open ifh2,"<ademails.txt"
@in2=<ifh2>
close ifh2;
chomp ifh2;
foreach (@in2)
{
($em)=(/mail: (.+)/);
if (exists $myhash{lc($em)} {print "Duplicate: $_\n"};
}


Now if you want to find all of your contacts that don't have email addresses assigned to them, that is easy

adfind -gc -b -f "&(objectcategory=person)(objectclass=contact)(!mail=*)" -dn


If you are using the othermailbox attribute as well for secondary emails then this gets more involved.

joe
 
C

Clay Calvert

I'm not getting your point on #1, I guess I don't understand what you are
trying to accomplish. Try explaining it a different way. You said in a
earlier post that you are "Looking for addresses in the list that exist in
AD". The script loops through each line of the text file and looks for that
email address in AD. If the address is found in AD, it prints out the
account name. If it's not found, it prints "No match".

Most of the addresses that shouldn't exist do NOT have users
associated with them. They are Contacts added to AD. Sorry I wasn't
clearer.
I don't know why it would fail to open the connection, I've only seen that
happen on NT4 machines. I've run the script on 2 Win2000 machines and one
XP machine. Try running it from a different machine? Try adding some more
error checking, in addition to "Err.Number" try getting the
"Err.Description" and see if that provides a clue.

Will do on Tuesday.

Thanks again.

Clay Calvert
(e-mail address removed)
Replace "W" with "L"
 
C

Clay Calvert

If the problem is, give me a list of all email addresses listed in AD and then check to see if any of the ones in a
given list are already in AD and you don't need to know anything else I would

Yes, that is it. Will give this a try on Tuesday. Thanks!
1. Use ADFIND or something else to dump all the email addresses in AD to a text file

adfind -gc -b -f mail=* mail |findstr /i mail:

which should give you output like:


2. Write up a little script to parse your list and throw the info into a vb dictionary object or a perl hash

open ifh1,"<emails.txt"
@in=<ifh1>
close ifh1;
chomp ifh1;
foreach (@in)
{
chomp;
$myhash{lc($_)}=1;
}


3. Parse through the generated file from AD and strip off the >mail: and then do a lookup in the hash

open ifh2,"<ademails.txt"
@in2=<ifh2>
close ifh2;
chomp ifh2;
foreach (@in2)
{
($em)=(/mail: (.+)/);
if (exists $myhash{lc($em)} {print "Duplicate: $_\n"};
}


Now if you want to find all of your contacts that don't have email addresses assigned to them, that is easy

adfind -gc -b -f "&(objectcategory=person)(objectclass=contact)(!mail=*)" -dn


If you are using the othermailbox attribute as well for secondary emails then this gets more involved.

joe

Clay Calvert
(e-mail address removed)
Replace "W" with "L"
 
C

Clay Calvert

Joe Richards said:
If the problem is, give me a list of all email addresses listed in AD and
then check to see if any of the ones in a
given list are already in AD and you don't need to know anything else I would

1. Use ADFIND or something else to dump all the email addresses in AD to a text file

adfind -gc -b -f mail=* mail |findstr /i mail:

Thanks Joe! This worked great and it wasn't even necessary to dump the AD
addresses to a text file. In fact, it wasn't even necessary to query the
whole directory. Instead of using "mail=*" it worked when using the entire
SMTP address ([email protected]), which minimizes hits against the catalog
servers. Here is the simplest form of script that gave enough information
(smtp.txt is simply a list of smtp addresses):

@echo off
for /f %%a in (smtp.txt) do adfind -gc -b -f mail=%%a mail

Adding ' 2>nul| find /i "%%a"' to the end makes the output a little cleaner,
so this is what will be used (2 lines):


@echo off
for /f %%a in (smtp.txt) do adfind -gc -b -f mail=%%a mail 2>nul| find /i
"%%a"

The only reason for the 2>nul is so that ADfind's banner will not be
displayed on each execution, which is no problem. I'm just sure some will
be wondering why StdErr is being ignored.

Thanks again! This worked for user addresses and contacts as well.
Clay
which should give you output like:


2. Write up a little script to parse your list and throw the info into a
vb dictionary object or a perl hash
open ifh1,"<emails.txt"
@in=<ifh1>
close ifh1;
chomp ifh1;
foreach (@in)
{
chomp;
$myhash{lc($_)}=1;
}


3. Parse through the generated file from AD and strip off the >mail: and then do a lookup in the hash

open ifh2,"<ademails.txt"
@in2=<ifh2>
close ifh2;
chomp ifh2;
foreach (@in2)
{
($em)=(/mail: (.+)/);
if (exists $myhash{lc($em)} {print "Duplicate: $_\n"};
}


Now if you want to find all of your contacts that don't have email
addresses assigned to them, that is easy
adfind -gc -b -f
"&(objectcategory=person)(objectclass=contact)(!mail=*)" -dn
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top