20070321 checking active directory for duplicate e mail addresses - plembo/onemoretech GitHub Wiki

title: Checking Active Directory for Duplicate E-Mail Addresses link: https://onemoretech.wordpress.com/2007/03/21/checking-active-directory-for-duplicate-e-mail-addresses/ author: lembobro description: post_id: 735 created: 2007/03/21 20:56:00 created_gmt: 2007/03/21 20:56:00 comment_status: open post_name: checking-active-directory-for-duplicate-e-mail-addresses status: publish post_type: post

Checking Active Directory for Duplicate E-Mail Addresses

Here’s an application using Net::LDAP’s module for Simple Paged Results Control.

Anyone whose environment depends on Microsoft Exchange for messaging knows what a pain duplicate e-mail addresses can be.
Following is a script I wrote to walk the Active Directory tree and do a quick lookup for duplicate addresses. It’s kind of raw, but it works. Uses a config file for host name, bind dn and password. Iterates through an array of the target containers specified. In this particular case we’ve got a separate container for what used to be known as “custom recipients”, users who don’t log into the domain but whose e-mail addresses we want to be searchable in the Exchange GAL. The script only reports on exact matches on the value of the ‘mail’ attribute in entries other than the current subject.

    
    
    #!perl
    # Check Active Directory for duplicate e-mail addresses.
    # Created 03/12/07 by P Lembo
    use strict;
    use Net::LDAP;
    use Net::LDAP::Entry;
    use Net::LDAP::Control::Paged;
    use Net::LDAP::Constant qw( LDAP_CONTROL_PAGED );
    #
    our($adHost,$adUsr,$adPass);
    require "c:/apps/etc/app.conf";
    my $errfile = "../addupchk.log";
    open LOGZ, ">$errfile" or die $!;
    #
    my $count=0;
    my $found=0;
    #
    my $contactbase = "ou=addressbook,dc=mydomain,dc=mycompany,dc=com";
    my $adroot = "dc=mycdomain,dc=mycompany,dc=com";
    my @allbases = ( "ou=users,dc=mydomain,dc=mycompany,dc=com",
         "ou=others,dc=mydomain,dc=mycompany,dc=com",
         "ou=addressbook,dc=mydomain,dc=mycompany,dc=com",
         );
     #
    my $query = "(mail=*)";
    my @attrs = qw(mail displayname cn);
    my $timestamp = localtime();
    print LOGZ "$timestamptBegin Checking AD for duplicate e-mailsn";
    #
    my $ldap = Net::LDAP->new($adHost) or die $!;
    my $mesg = $ldap->bind($adUsr, password =>$adPass);
    #
    foreach my $base(@allbases) {
        my $page = Net::LDAP::Control::Paged->new( size => 1000 ) or die $!;
        my @args = ( base => $base,
               scope => 'sub',
               filter => $query,
               attrs => @attrs,
               control => [ $page ],
          );
    #
    	
        my $cookie;
    #
        while (1) {
            $mesg = $ldap->search ( @args ) or die $!;
    #
            while (my $entry = $mesg->shift_entry()) {
                my $entrydn = $entry->dn();
                my $mail = $entry->get_value('mail');
                my $displayname = $entry->get_value('displayname');
                my $cn = $entry->get_value('cn');
    #
                if($mail !~ /.+@.+/g) {
                    print "$entrydn not mail-enabledn";
                }
                else {
                    my @hits = dup_search($entrydn,$mail,$displayname,$cn);
                    foreach my $hit(@hits) {
                        if($hit =~ /$entrydn/) {
                       # Same entry, move on
                        }
                        else {
                            print "t$displayname $entrydn mail same asn";
                            print "t$hitnn";
                            print LOGZ "t$displayname $entrydn mail duplicate foundn";
                            print LOGZ "t$hit should be deleted from contactsnn";
                            $count++;
                         } #else
                    } #foreach
               } # else
           } # while
    #
           my ($resp) = $mesg->control(LDAP_CONTROL_PAGED) or last;
           $cookie = $resp->cookie or last;
           $page->cookie($cookie);
    	
        } # while (1)
    #
        if ($cookie) {
            $page->cookie($cookie);
            $page->size(0);
            $ldap->search( @args );
       }
    	
    } # foreach
    #
    close FH;
    $ldap->unbind;
    #
    $timestamp = localtime();
    print "Number of hits: $countn";
    print LOGZ "$timestamptChecking completedn";
    close LOGZ;
    #
    sub dup_search {
     my $addn = @_[0];
     my $admail = @_[1];
     my $displayname = @_[2];
     my $cn = @_[3];
     print "$addn $admailn";
     my @matchdns;
     my $nldap = Net::LDAP->new($adHost) or die $!;
     my $nmesg = $nldap->bind($adUsr, password =>$adPass);
     my $nquery = "(mail=$admail)";
     my @nattrs = qw(mail displayname cn);
     my $npage = Net::LDAP::Control::Paged->new( size => 1000 ) or die $!;
     my @nargs = ( base => $contactbase,
             scope => 'sub',
             filter => $nquery,
             attrs => @nattrs,
             control => [ $npage ],
         );
     my $ncookie;
     while (1) {
         $nmesg = $nldap->search ( @nargs ) or die $!;
         while (my $nentry = $nmesg->shift_entry()) {
              my $nentrydn = $nentry->dn();
              my $ndisplayname = $nentry->get_value('displayname');
              my $acn = $nentry->get_value('cn');
              push @matchdns, $nentrydn;
          }
          my ($nresp) = $nmesg->control(LDAP_CONTROL_PAGED) or last;
          $ncookie = $nresp->cookie or last;
          $npage->cookie($ncookie);
     }
     if ($ncookie) {
        $npage->cookie($ncookie);
        $npage->size(0);   $nldap->search( @nargs );
     }
      return @matchdns;
      $nldap->unbind;
    }
    #
    __END__;

_Note: In the process of reformatting this big hunk of code in the wake of migrating to WordPress, I’ve come to appreciate the efforts of all those technical editors out there who do this every day.
_

Copyright 2004-2019 Phil Lembo