http://www.perlmonks.org?node_id=552818


in reply to Change AD password

You can also do this from a non-Windows machine (without Win32). AD can be accessed through LDAP. I use the following at work. You'll have to change some of the specifics for your particular situation. (i.e. The DN, and the username and password to bind with)

Note: This was cut from a larger script, so there may be a bit here or there missing.

use strict; use warnings; use Net::LDAP; use Unicode::Map8; use Unicode::String qw(utf16); my $defaultpass = 'default'; my $cn = 'Person to Change'; my $baseDN = "OU=GENERAL USERS,OU=USERS,DC=FOO"; my $ldap = Net::LDAP->new( 'ldaps://ad.foo' ) or return; $ldap->bind( "cn=$uid,$baseDN", password => "$password"); my $searchDN = "OU=GENERAL USERS,OU=USERS,DC=FOO"; my $mesg = $ldap->search( # perform a search base => "$searchDN", filter => "(&(objectCategory=person)(cn=$cn +))", ); if ($mesg->entries != 1) { print "ERROR: Too many or too few users found"; $ldap->unbind; exit; } foreach my $entry ($mesg->entries) { # build the conversion map from your local character set to Unicod +e my $charmap = Unicode::Map8->new('latin1') or die; # surround the PW with double quotes and convert it to UTF-16 # byteswap() was necessary in experiments on i386 Linux, YMMV my $newUniPW = $charmap->tou(qq/"$newpass"/)->byteswap()->utf16(); $entry->replace(unicodePwd => $newUniPW); # Require pass change on next login $entry->replace(pwdLastSet => 0); # Update LDAP Entry my $msg = $entry->update($ldap); $msg->sync; if ($msg->is_error()) { print $msg->error_text(); $ldap->unbind; exit; } else { print "Password reset to $newpass"; } }