Scraping Active Directory E-mail Addresses using PowerShell

In my day-to-day software development activities, I rarely use PowerShell. My programming tasks don’t hit PowerShell’s sweet spot of between simple (when I use a .bat file) and more complex (when I use C#). But for one specific task — finding e-mail addresses on an Active Directory network — a neat PowerShell script is my utility of choice.


My PowerShell script is named makeDistList.ps1 and starts with some documentation comments:

# makeDistList.ps1 
# create an e-mail list of certain employees.
# run as C:\> .\makeDistList.ps1 to view on screen
# run as C:\> .\makeDistList.ps1 > mylist.txt to save

# "cn" -- common name, first name & last name
# "sn" -- surname
# "givenName" -- first name
# "name" -- usually same as 'cn' but not always
# "mail" -- e-mail address
# "company" -- like 'Acme'
# "title" -- for some employees only
# "manager" -- employee's manager
# "description" -- misc. info such as '(Sponsor: jLee)'
# "department" -- Cost Center name
# "telephoneNumber" -- office phone number

# set up attribute of AD users to search for
# Examples:
#$target = "(&(objectCategory=User)(Title=*SDET*))"
# users with 'SDET' in their job titles

#$target = "(&(objectCategory=User)(company=*Acme*))"
# users who are contractors through Acme

#$target = "(&(objectCategory=User)(telephoneNumber=*706*))" 
# users whose phone number contains '702'

Next, I set up a wonky .NET DirectorySearcher object:

$root = new-object directoryServices.directoryEntry
$seeker = new-object directoryServices.directorySearcher
$seeker.searchRoot = $root
$seeker.SearchScope = "Subtree"
$seeker.serverTimeLimit = -1
$seeker.clientTimeout = -1
$seeker.filter = $target
$seeker.pageSize = 10

Then I set up which AD fields to retrieve (in this case, user name and e-mail address):

$colProplist = "cn", "mail"
foreach ($i in $colPropList) {
 $seeker.PropertiesToLoad.Add($i) | out-null

Next I set up any users I want to exclude in an array:

$omitList = @("", "")

Now, invoke and show how many users were found:

$resultsCollection = $seeker.findAll()
write-host $resultsCollection.Count  

The hardest part was figuring out how to extract the results from the return object, and display them:

# create the list of e-mail addresses
$allMail = ""
foreach ($result in $resultsCollection) {           
  $propertiesCollection = $result.Properties  

  $mailValues = $propertiesCollection.mail          
  if ($mailValues -eq $null) {
    write-host "No mail found for: ", $
  else {
    $mailString = $mailValues.Item(0)
    $addIt = $true

    foreach ($m in $omitList) {
      if ($m -eq $mailString) {
        write-host "NOT adding", $mailString
        $addIt = $false

    # omit special cases
    if ($mailString.Contains("toronto")) {
      $addIt = $false

    if ($addIt -eq $true) {
      write-host "Adding", $mailString
      $allMail += $mailString + ";"
  } #else                                               
} #foreach $result

The script finishes by adding in special people and displaying the results:

$allMail += ";;"
write-output $allMail # show results!
write-host "Done"
# end script

I use this PowerShell script, or some variation of it, quite often. For generating e-mail addresses, PowerShell is an excellent tool for me.

This entry was posted in Miscellaneous. Bookmark the permalink.