In regard to: Perl-Win32-Users Digest, Vol 61, Issue 7, perl-win32-users-re...:

> Exchange uses any SMTP values in lowercase (eg
> smtp:co...@angloirishbank.ie) as aliases, and will stamp outgoing SMTP
> email with the value that starts with SMTP: uppercase (eg
> SMTP:conorlil...@angloirishbank.ie).
>
> I have attached below the script I am trying to use for proof of
> concept, and while I am able to retrieve the current attribute values, I
> am unable to successfully write the new values to AD.
> I should clarify that I am basing the script on previous working scripts
> and various articles on the web, and am not a full time coder so layout
> / coding is not necessarily optimum ;-)
>
> Any assistance greatly appreciated. I am testing in disabled accounts in
> the OU below so as not to impact on live accounts...
>
>
> system("cls");
> use Net::LDAP;

You should probably "use warnings", and I generally also program with
"use strict";, though that will force additional changes that you may
not want to bother with.

> my $PDC = "PDC.domain.lan";
> my $userid = "UserID\@domain.lan";
> my $password = "Password";
> my $newdomain = "NewDomain.com";
> my $base = "ou=Disabled
> Accounts,ou=IOM,ou=angloirishbank,DC=anglo,DC=lan";
>
> my $ad = Net::LDAP->new("$PDC") || die "Could not connect!";

I don't know what the AD security requirements are, but some native
LDAP servers require that changes be done over a secure connection.
You may therefore want to look into doing a "start_tls()" on the
connection, before you do the bind.  Your AD server would have to
support TLS, obviously.

> $ad->bind(dn =>"$userid", password=>"$password") || die $^E;

I don't think you want to use this idiom for error checking.  The problem
is that when Net::LDAP methods are called, they generally return a
Net::LDAP::Message object as a result, even on error.  That means that
there's a potential that the "die" wouldn't be executed even when the
bind didn't succeed, because a valid object is returned.

You're much better off doing something like

        my $bind_message = $ad->bind(
                                                        dn      =>      $userid,
                                                        password        =>      
$password
        );
        if ($bind_message->is_error()) {
                die "Failed to bind to $PDC as $userid: ",
                        $bind_message->error_text(), "\n";
        }

or something along those lines.

Basically, check the documentation for each of the methods you're calling
and find out what it returns on error.  If it returns a Net::LDAP::Message,
you'll want to assign that to something and then use methods from it to
check for errors and spit out appropriate error messages.

> my @args =
> (
>       base     => $base,
>       filter => "(mail=*)",
>       attrs  => "proxyAddresses",
> );

attrs should be an array, though the LDAP module is probably smart enough
to let you get away with this.

> my $results = $ad->search(@args);

I don't know about AD, but traditional LDAP servers might set a sizelimit
for returned entries.

> my $count = $results->count;
> print "Count = $count\n";
> my $entry;
> my $counter;
> for (my $i=0; $i<$count; $i++)
> {
>       $entry = $results->entry($i);
> #     Get First Name and Surname for new SMTP address to be
> firstname.surn...@domain.com
>       my $FirstName = ($entry->get_value('givenName'));
>       my $SurName = ($entry->get_value('sn'));

I don't know why you're putting the extra ( ) around this.  You're
also not checking that they actually exist, though perhaps the AD schema
mandates that.

>       @proxyAddresses =$entry->get_value('proxyAddresses');
>       my $arraycount = 0;
>
> #     Set all existing SMTP addresses to lowercase,  Use $arraycount
> variable to update record within array
>       foreach my $Proxy(@proxyAddresses)
>       {
>               if (grep /SMTP:/, $Proxy)
>               {
>                       $Proxy=lc($Proxy);
>                       $proxyAddresses[$arraycount]=$Proxy;
>               }
>               ++$arraycount;
>               print "$name\tOLD\t:\t$Proxy\n";
>       }
>       if (!grep /SMTP:$FirstName.$SurName\@$newdomain/i,
> @proxyAddresses)
>       {
>
> push(@proxyAddresses,"SMTP:$FirstName.$SurName\@$newdomain");
>       }

That whole section could be simplified if you built a new array and
used it going forward, rather than keeping the one you had, but I don't
think any of the code there is the source of your issues.  I wouldn't
use grep in the first if against a scalar (just use a regex comparison)
and I'm not certain why you have the /i at the end of the test for the
newdomain (don't you want an exact case match there?).

> #     Print the new array to ensure appropriate values have been added
> / changed
>
>       foreach my $Proxy(@proxyAddresses){print
> "$name\tNEW\t:\t$Proxy\n";}
>
> #     Update AD (hopefully)
>
>       $entry->replace('proxyAddresses',@proxyAddresses);
>       $entry->update($ad)|| die print "There was an error updating

Is proxyAddresses multivalued, or is it a single attribute containing
multiple strings somehow concatenated?  If it is multivalued, you want
an array reference there, not an array.

Is your script ever die'ing here?  What happens if you change to

        my $update_message = $entry->update($ad);
        if ($update_message->is_error()) {
                die "Error updating $name: ",
                        $update_message->error_desc(), "\n";
        }

>       print "\nRetrieving NEW SMTP Values\n\n\n";
>       my @proxyAddresses =$entry->get_value('proxyAddresses');
>       foreach my $Proxy(@proxyAddresses){print
> "$name\tADSI\t:\t$Proxy\n";}
> }

-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.

_______________________________________________
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to