For Windows Exchange Server running on Windows Server 2000/2003, from Exchange and Active Directory, get all email addresses (and aliases) from all active users. Uses ASDI scripting, LDAP paths to get user info from Active Directory. Uses Pythonwin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | from win32com.client import (
GetObject,
Dispatch,
)
from pythoncom import (
com_error,
)
# --------- #
Connection = Dispatch("ADODB.Connection")
Connection.Open("Provider=ADSDSOObject")
# --------- #
class Bunch(dict):
def __init__(self,**kw):
dict.__init__(self,kw)
self.__dict__ = self
def LDAP_select_all_iterator(LDAP_path_str):
R = Connection.Execute(
"SELECT * From '%s'" % LDAP_path_str)[0]
while not R.EOF:
d = Bunch()
for f in R.Fields:
d[f.Name] = f.Value
yield d
R.MoveNext()
class LDAP_ObjectWrapper(object):
def __init__(self, WINCOM_LDAP_Object):
self._o = WINCOM_LDAP_Object
@classmethod
def from_LDAP_path(cls, LDAP_path_str):
return cls(GetObject(LDAP_path_str))
def __getattr__(self, name):
try:
return getattr(self._o, name)
except (AttributeError, com_error):
pass
try:
return self._o.Get(name)
except com_error:
raise AttributeError
raise AssertionError
def GetInfo(self):
self._o.GetInfo()
# --------- #
defaultNamingContext = (
LDAP_ObjectWrapper.from_LDAP_path(
'LDAP://rootDSE').defaultNamingContext)
# --------- #
results = {}
def _latin_lower(u):
return u.encode('latin-1').lower()
for r in LDAP_select_all_iterator(
'LDAP://CN=Users,%s' % (defaultNamingContext,)):
UserObject = LDAP_ObjectWrapper.from_LDAP_path(r.ADsPath)
UserObject.GetInfo()
if getattr(UserObject, 'AccountDisabled', False):
continue
try:
proxyAddresses = list(UserObject.proxyAddresses)
except (AttributeError, TypeError):
proxyAddresses = []
if not proxyAddresses:
continue
email_addresses = []
for s in proxyAddresses:
if s.startswith('SMTP:'):
email_addresses.append(
('MAIN', _latin_lower(s[5:])))
elif s.startswith('smtp:'):
email_addresses.append(
('alias', _latin_lower(s[5:])))
if not email_addresses:
continue
email_addresses.sort()
misc_info = []
for n in ['displayName', 'name', 'description']:
try:
v = getattr(UserObject, n)
except AttributeError:
pass
else:
if v:
misc_info.append(
repr(v.encode('latin-1')))
assert misc_info
description_str = ' '.join(misc_info)
key = email_addresses[0][1]
assert key not in results
results[key] = (description_str, email_addresses)
for (i, key) in enumerate(sorted(results.keys())):
description_str, email_addresses = results[key]
print i, description_str
for t in email_addresses:
print ' %-5s %s' % t
|
Was setting up 3rd party spam filtering, and wanted to get the authorative list of active email address and aliases from the Exchange server itself. Microsoft's Scripting Guide and ADSI Scriptomatic were woe-fully inadequate. Was not able to find any script in any language that would automatically discover all email addresses. This was my first attempt at ADSI scripting, and I am pretty happy with the results. My next project will be doing authoratative reporting on user security groups. I used some features of Python 2.3 and 2.4, but it would be trivial to modify for earlier Python versions. In anticipation of futher ADSI scripting, I created iterators and wrappers that cleaned up the look of the code.
Thanks! This was very useful for me. I'm modifying the gnatsparse script that comes with Bugzilla. GNATS users are listed in a firstname.lastname format, and the bug reporter can be any email address or alias. With this, I can look up all that information and make sure to pick a real user. Very cool!
Question about this script. I need to extract all smtp addresses from AD, and this looks like it will do that, but I don't know anything about Python. Is this something I have to purchase to be able to use? Is there a runtime version or something? Thanks for any help.
cool, how do i use it? Hi, this can be a useful scrip, how do i use it?
Also, i would really appreciate if you could explain a little bit how the scripts works.
Thanks
Rezuma
Small Business Users. This scripts is really great..
Question: how can I change the query from CN=Users of Active Directory to MyBusiness/Users/SBSUsers ?
With this script I can capture all users from Container Users but I cannot capture the Users from domain.local/MyBusiness/Users/SBSUsers Organizational unit..
please help you can email me at bobby@seerx.com
Thanks