Win32::AD::User - provides routines for Active Directory user administration.


Win32-AD-User documentation Contained in the Win32-AD-User distribution.

Index


Code Index:

NAME

Top

Win32::AD::User - provides routines for Active Directory user administration.

SYNOPSIS

Top

 use Win32::AD::User;

 $user = AdUser->new( ADS_CONNECT_STRING, USER_REFERENCE_STRING );

 $user->print_me();

 $user->create_new();

 $user->get_info();

 $user->lock();

 $user->un_lock();

 $user->is_locked();

 $user->set_properties( PROPERTY_HASH );

 $user->set_property( ADS_PROPERTY_NAME, PROPERTY_VALUE );

 $user->get_properties( ADS_PROPERTY_LIST );

 $user->get_property( ADS_PROPERTY_NAME );

 $user->delete();

 $user->set_password( PASSWORD_STRING );

 $user->rename( USER_REFERENCE_STRING );

 $user->move( ADS_CONNECT_STRING );

 $user->get_groups();

 $user->add_to_group( ADS_GROUP_STRING );

 $user->remove_from_group( ADS_GROUP_STRING );

 $user->get_ou_member_list( SEARCH_MASK );

ABSTRACT

Top

Administer user in Active Directory using either LDAP or WinNT AdsPath.

DESCRIPTION

Top

Connect to an Active Directory (AD) Server and Administer Users. Below there is more information on each of the various functions of an Win32::AD::User object.

new( ADS_CONNECT_STRING, USER_REFERENCE_STRING );

The new function returns an Win32::AD::User object. The function takes 2 scalars; ADS_CONNECT_STRING and USER_REFERENCE_STRING. The ADS_CONNECT_STRING can be a valid LDAP or WinNT ADsPath string. More information about a valid ADsPath String is available via the Win32::OLE documentation. The USER_REFERENCE_STRING is the username of the account you would like to either create or modify.

create_new();

The 'create_new' function will create a new user object on the AD Server. The 'new' function does not actualy connect to the AD Server either 'create_new or 'get_info' must be used to connect to the AD Server properly.

get_info();

The 'get_info' function will get the user information from the AD Server. The 'new' function does not actualy connect to the AD Server either 'create_new or 'get_info' must be used to connect to the AD Server properly.

lock();

The 'lock' function will lock a user account.

un_lock();

The 'un_lock' function will unlock a user account.

is_locked();

The 'is_locked' function returns '0' if the account is not locked and '1' if it is locked.

set_properties( PROPERTY_HASH );

The 'set_properties' function will set all properties sent in as PROPERTY_HASH. PROPERTY_HASH is a hash where every key is a valid ADS_PROPERTY_NAME and that key's value is a valid PROPERTY_VALUE. Both of which are defined in the 'set_property' function.

set_property( ADS_PROPERTY_NAME, PROPERTY_VALUE );

The 'set_property' function will allow you to set any user property. The function take two scalars ADS_PROPERTY_NAME, and PROPERTY_VALUE. ADS_PROPERTY_NAME is the name of the property as defined in the ADSI Specification. The ADSI Browser by Toby Everett is a great tool for figuring out which ADS_PROPERTY_NAME you want to use. The PROPERTY_VALUE is what you would like to store in AD.

get_properties( ADS_PROPERTY_LIST );

The 'get_properties' function will return a hash of elements where every key is an element from the ADS_PROPERTY_LIST that is sent is to the funciton as the only argument. The ADS_PROPERTY_LIST is a list of ADS_PROPERTY_NAME elements, as defined in the 'set_property' function description.

get_property( ADS_PROPERTY_NAME );

The 'get_property' function returns a scalar that is the value of the ADS_PROPERTY_NAME which is sent in as an argument. The ADS_PROPERTY_NAME is defined in the 'set_property' function description.

delete();

The 'delete' function will delete the user object from the AD Server. Note that this will not destroy any other data in the Win32::AD::User object, you can recreate user account (without any of the previous attiributes) by invoking the 'create_new' function after using the 'delete' function.

set_password( PASSWORD_STRING );

The 'set_password' function will set the password of the user. This function requires one scalar; PASSWORD_STRING. This string is what will become the user's password.

rename( USER_REFERENCE_STRING );

The 'rename' function will change the user's name from whatever it is to the value supplied as USER_REFERENCE_STRING. USER_REFERENCE_STRING is defined in the 'new' function description.

move( ADS_CONNECT_STRING );

The 'move' function will change the user's location in AD. The function requires an ADS_CONNECT_STRING. The ADS_CONNECT_STRING is defined in the 'new' function description.

get_groups();

The 'get_groups' function will return a list of groups of which the user is a member.

add_to_group( ADS_GROUP_STRING );

The 'add_to_group' function will add the user to the group specified in the ADS_GROUP_STRING. The ADS_GROUP_STRING is an ADS_CONNECT_STRING for a group object. The ADS_CONNECT_STRING is defined in the 'new' function description. If a full ADS_GROUP_STRING is given it will attempt to build a WinNT:// ADS_CONNECT_STRING for your user and group (based on the string supplied) to perform the user's addition to the group.

remove_from_group( ADS_GROUP_STRING );

The 'remove_from_group' function will remove the user from the group specified in the ADS_GROUP_STRING. The ADS_GROUP_STRING is an ADS_CONNECT_STRING for a group object. The ADS_CONNECT_STRING is defined in the 'new' function description. If a full ADS_GROUP_STRING is given it will attempt to build a WinNT:// ADS_CONNECT_STRING for your user and group (based on the string supplied) to perform the user's removal from the group.

get_ou_member_list( SEARCH_MASK );

The 'get_ou_member_list' function will return a list of objects in the OU given as your ADS_CONNECT_STRING. Note, this will only work for an LDAP:// ADS_CONNECT_STRING. SEARCH_MASK refers to a string that will be use to filter the list of objects returned. For example if you only are intrested in CN objects use the mask "CN=". The SEARCH_MASK is case sensitive.

AUTHOR

Top

Aaron Thompson <thompson@cns.uni.edu>

COPYRIGHT

Top

SEE ALSO

Top

Win32::OLE; ADSI Browser; perl;


Win32-AD-User documentation Contained in the Win32-AD-User distribution.

package Win32::AD::User; 
  use strict;
  use Win32::OLE 'in';
  $Win32::OLE::Warn = 3;
  our $VERSION = '0.04';

######################################################################
sub new{
  my $class = shift;
  my ($connect_string,$username) = @_;
  warn "Win32::AD::User -- Warning ADS_CONNECT_STRING not defined.\n"  if(not defined $connect_string);
  warn "Win32::AD::User -- Warning USER_REFERENCE_STRING not defined.\n" if(not defined $username);
  bless { _connect_string => $connect_string,
          _username       => $username,
          _LDAPAdsPath    => ($connect_string =~ /LDAP/) ? "CN=".$username.",".(split /\//,$connect_string)[3] : undef,
          _LDAPAdsSvr     => ($connect_string =~ /LDAP/) ? (split /\//,$connect_string)[2] : undef,
          _WinNTAdsPath   => ($connect_string =~ /WinNT/) ? "WinNT://" . (split /\//,$connect_string)[2] . "/$username,user" : undef,
          _WinNTDomain    => ($connect_string =~ /WinNT/) ? (split /\//,$connect_string)[2] : (split /\./, (split /\//,$connect_string)[2])[0],
          _user_ref       => undef}, $class; 
}

######################################################################
sub print_me{ 
  my $self = shift; print "$_: $self->{$_}\n" for (keys %$self)}

######################################################################
sub create_new{
  my $self = shift;
  my $server = Win32::OLE->GetObject($self->{_connect_string});
  my $user;

  if ($self->_connect_type eq "LDAP"){
    $user = $server->Create("user","cn=".$self->{_username});
    $user->{samAccountName}=$self->{_username};
    $user->SetInfo();
  }
  else{
    $user = $server->Create("user",$self->{_username});
    $user->SetInfo();
  }#fi
  $self->{_user_ref} = $user;
}

######################################################################
sub get_info{
  my $self = shift;
  my $user;

  if ($self->_connect_type eq "LDAP"){
    $user = Win32::OLE->GetObject( join "/", ("LDAP:/",$self->{_LDAPAdsSvr},$self->{_LDAPAdsPath}) );
  }
  else{
    $user = Win32::OLE->GetObject($self->{_WinNTAdsPath}); 
  }#fi
  $self->{_user_ref} = $user;
}

######################################################################
sub delete{
  my $self = shift;
  my $server = Win32::OLE->GetObject($self->{_connect_string});
  if ($self->_connect_type eq "LDAP"){
    $server->Delete("user","cn=".$self->{_username});
  }
  else{
    $server->Delete("user",$self->{_username}); 
  }#fi
  $self->{_user_ref} = undef;
}

######################################################################
sub set_password{
  my $self = shift;
  my ($new_password) = @_;
  $self->{_user_ref}->SetPassword($new_password);
}

######################################################################
sub lock{
  my $self = shift;
  $self->{_user_ref}->{'AccountDisabled'} = '1';
  $self->{_user_ref}->SetInfo();
}

######################################################################
sub un_lock{
  my $self = shift;
  $self->{_user_ref}->{'AccountDisabled'} = '0';
  $self->{_user_ref}->SetInfo();
}

######################################################################
sub is_locked{
  my $self = shift;
  $self->{_user_ref}->{'AccountDisabled'};
}

######################################################################
sub set_properties{
  my $self = shift;
  my ($properties) = @_;
  for my $i (keys %$properties){
    $self->{_user_ref}->{$i} = $properties->{$i};
  }#rof
  $self->{_user_ref}->SetInfo();
}

######################################################################
sub set_property{
  my $self = shift;
  my ($property,$value) = @_;
  $self->{_user_ref}->{$property} = $value;
  $self->{_user_ref}->SetInfo();
}

######################################################################
sub get_properties{
  my $self = shift;
  my @props = @_;
  my %props;
  $props{$_}=$self->{_user_ref}->{$_} for (@props);
  %props;
}

######################################################################
sub get_property{
  my $self = shift;
  my ($property) = @_;
  $self->{_user_ref}->{$property};
}

######################################################################
sub _connect_type{
  my $self = shift;
  ($self->{_connect_string} =~ /^LDAP/) ? return "LDAP" : return "WinNT";
}

######################################################################
sub rename{
 ## Inspiration: 
 # http://www.rallenhome.com/books/adcookbook/src/06.06-rename_user.pls.txt
  my $self = shift;
  my ($new_name) = @_;
  my $old_name = $self->{_username};
  my $server = Win32::OLE->GetObject($self->{_connect_string});
  
  if ($self->_connect_type eq "LDAP"){
    $self->set_property("samAccountName",$new_name);
    $server->MoveHere( join ("/", ("LDAP:/",$self->{_LDAPAdsSvr},$self->{_LDAPAdsPath})),"cn=".$new_name);
    for my $key (keys %$self){
      if ($self->{$key} =~ /$old_name/){
        $self->{$key} =~ s/$old_name/$new_name/g
      }#fi 
    }#rof
    $self->get_info();
  }
  else{
    warn "Win32::AD::User -- The 'rename' function is not available when using \n",
         "a WinNT:// ADsPath... use a LDAP:// ADsPath.\n";
  }#fi
}

######################################################################
sub move{
 #Inspiration:
 # http://www.rallenhome.com/books/adcookbook/src/08.04-move_computer.pls.txt
  my $self = shift;
  my ($new_connect) = @_;

  if ($self->_connect_type eq "LDAP"){
    my $server = Win32::OLE->GetObject($new_connect);
    $server->MoveHere($self->{_user_ref}->{'ADsPath'},$self->{_user_ref}->{'Name'});
    $self->{_connect_string} = $new_connect;
    $self->{_LDAPAdsPath}    = "CN=".$self->{_username}.",".(split /\//,$self->{_connect_string})[3];
    $self->{_LDAPAdsSvr}     = (split /\//,$self->{_connect_string})[2];
    $self->get_info();
  }
  else{
    warn "Win32::AD::User -- The 'move' function is not available when using \n",
         "a WinNT:// ADsPath... use a LDAP:// ADsPath.\n";
  }#fi
  
}

######################################################################
sub get_groups{
  my $self = shift;
  my @grp;
  push(@grp, $_->{Name}) for (in $self->{_user_ref}->{Groups});
@grp;
}

######################################################################
sub add_to_group{
 #Inspiration & Reference:
 # http://www.rallenhome.com/books/adcookbook/src/06.15-set_primary_group.pls.txt
 # http://www.rallenhome.com/books/adcookbook/src/07.04-add_group_member.pls.txt
  my $self = shift;
  my ($group_ads_path) = @_;
  $group_ads_path = "WinNT://".$self->{_WinNTDomain}."/$group_ads_path,group" if ($group_ads_path !~ /\:\/\//);
  my $group = Win32::OLE->GetObject($group_ads_path);

  if ($self->_connect_type eq "LDAP"){
    if($group_ads_path =~ /WinNT:/){
      my $wintmp = "WinNT://".$self->{_WinNTDomain}."/".$self->{_username}.",user";
      $group->Add($wintmp);
    }
    else{
      $group->Add("LDAP://".$self->{_LDAPAdsPath});
    }#fi
    $group->SetInfo();
    $self->get_info();
  }
  else{
    $group->Add($self->{_WinNTAdsPath});
    $group->SetInfo();
  }#fi
}

######################################################################
sub remove_from_group{
 #Inspiration & Reference:
 # http://www.rallenhome.com/books/adcookbook/src/06.15-set_primary_group.pls.txt
 # http://www.rallenhome.com/books/adcookbook/src/07.04-add_group_member.pls.txt
  my $self = shift;
  my ($group_ads_path) = @_;
  $group_ads_path = "WinNT://".$self->{_WinNTDomain}."/$group_ads_path,group" if ($group_ads_path !~ /\:\/\//);
  my $group = Win32::OLE->GetObject($group_ads_path);
  
  if ($self->_connect_type eq "LDAP"){
    if($group_ads_path =~ /WinNT:/){
      my $wintmp = "WinNT://".$self->{_WinNTDomain}."/".$self->{_username}.",user";
      $group->Remove($wintmp);
    }
    else{
      $group->Remove("LDAP://".$self->{_LDAPAdsPath});
    }#fi
    $group->SetInfo();
    $self->get_info();
  }
  else{
    $group->Remove($self->{_WinNTAdsPath});
    $group->SetInfo();
  }#fi
}

######################################################################
sub get_ou_member_list{
 #Inspiration & Reference:
 # http://www.rallenhome.com/books/adcookbook/src/05.03-enumerate_children.pls.txt
  my $self = shift;
  my ($search_mask) = @_;
  my @members;
  my $parent_ou = Win32::OLE->GetObject($self->{_connect_string});
  if ($self->_connect_type eq "LDAP"){
    for my $child (in $parent_ou) {
      push(@members, $child->Name) if (defined $search_mask && $child->Name =~ /$search_mask/);
      push(@members, $child->Name) if (not defined $search_mask);
    }#rof 
  }
  else{
    warn "Win32::AD::User - The 'get_ou_member_list' function is not available when using \n",
         "a WinNT:// ADsPath... use a LDAP:// ADsPath.\n";
  }#fi
@members;
}

1;

__END__