use it like this: disable.pl --server domaincontroller.example.com --bindDN cn=privileged_user,dc=example,dc=com --password --searchbase dc=example,dc=com --infile --server: one of your domain controllers --bindDN: the DN of an account with appropriate privileges (e.g. cn=administrator,ou=built-in,dc=example,dc=com --password: above accounts password --searchbase: where the search should start, e.g. dc=example,dc=com, or ou=students,dc=example,dc=com --infile: file with the list of users to be disabled (I'll also include as an attachment because the formatting will probably get horked in email) ---begin file--- use strict; use Net::LDAP; use Getopt::Long; my $ldap_server; my $bind_privileged_user; my $bind_privileged_password; my $searchbase; my $infile; my %status = ( 'NORMAL_ACCOUNT' => 512, 'ACCOUNT_DISABLED' => 514 ); GetOptions( "server=s" => \$ldap_server, "bindDN=s" => \$bind_privileged_user, "password=s" => \$bind_privileged_password, "searchbase=s" => \$searchbase, "infile=s" => \$infile ); if( !$ldap_server || !$bind_privileged_user || !$bind_privileged_password || !$infile || !$searchbase) { die help(); } #open input file # open(F, "<$infile") or die "unable to open $infile: $!\n"; #connect to active directory # my $cs = 'ldap://' . $ldap_server; my $ldap = Net::LDAP->new($cs) or die "could not connect to $cs."; #bind with privileged account # $ldap->bind($bind_privileged_user, password=>$bind_privileged_password) or die "failed to bind to $cs as $bind_privileged_user."; while() { chomp; my $username = $_; #filter results # my $filter = "(&(objectClass=user)(objectCategory=person)(sAMAccountname=$username))"; my $results = $ldap->search(base=>$searchbase, filter=>$filter); #Everyone ok? # $results->code && die $results->error; if( $results->count != 1 ) { warn "$username: more or less than one result returned. skipping.\n"; } #get entry and make modification # my $entry = $results->entry(0); if( defined $entry ) { $entry->replace(userAccountControl => $status{ACCOUNT_DISABLED}); my $res = $entry->update($ldap); if( !$res->code ) { print "disabled account: ", $entry->dn, "\n"; } else { warn "updated failed, account not disabled:", $res->error, "\n"; } } else { warn "invalid ldap entry object, skipping...\n"; next; } } close F; $ldap->unbind(); sub help { print "usage: $0 --server --bindDN --password --searchbase --infile \n"; } --- end file ---