|
Setting up a Windows 2000 environment with server and clients meant we
got to have a active directory server as well. We were quite relieved to
find that Microsoft has created an API for working with the Active Directory
called ADSI.
This allows to manage all elements of the active directory with the
execption of Group Policy Objects (For which Microsoft has chosen not to
publish and API)
You can find quite a lot of Information about using ADSI from C++ and
Visual Basic Script. But because we rather prefer to hack in perl we had to
figure out how todo things from within perl. In the following Sections I
will explain how to use ADSI from perl. I will do the ubiquitous Account
Creation Example but mine realy works. Once you have understood how to
use ADSI from within perl, the Official ADSI documentation contained in the
ADSI 2.5 package from Microsoft helps a lot. Translating the code sample
from VBS to Perl is quite easy. Most of the Information is also acessible
directly on the eb, if you go to MSDN.

Perl for Windows contains a set of windows specific modules in the
Win32 hierarchy. Especially useful in our situation is the
Win32::OLE module and its friends. Because it allows to use
OLE. Which is exactly what you need to tap the ADSI library.
Start your ADSI Perl scripts like this:
use Win32::OLE; # base functionality
use Win32::OLE::Variant; # support for OLE data types
use Win32::OLE::Const ('Active DS'); # Load ADSI Constants
The Variant module allows you to work with data which uses the
Variant data type. You need this when you want to pass strings
to ADSI which contain the NUL character (ASCII 0). Generally the NUL
character is used to end a string, but in Active Directory context, it
happens that you actually have to pass a string containing the NUL
character into an ADSI function. NUL is not a problem for perl, but
the OLE interface usually converts Perl strings to char*.
my $variant = Variant(VT_UI1, "start".chr(0)."end");
The Const module can load constants from an OLE provider and make
them available within the perl script. The tricky part is to know under
which name these constants are available. (Information on this would be
highly appreciated.). Once you have loaded the constants you can readily
access them check out the
list of ADSI enumerations for inspiration.
You can find further information about the OLE perl modules in the appropriate
pod documentation. in the documentation provided with Windows Perl.

The main reason we have to modify the active directory is for the
creation of user accounts and addition of new machines into the active
directory structure. To ease this process we created a perl module
which encapsulates most interactions with the active directory.
You can download the ActiveDirectory.pm from the
download section of this website.
by Tobias Oetiker <oetiker@ee.ethz.ch>
David Schweikert <dws@ee.ethz.ch>
use ISG::Win32::ActiveDirectory qw(AD_add_object mac2guid);
AD_add_object "OU=my_department,OU=company",
'organizationalUnit',
{ Description => 'My Department' };
AD_add_object "CN=department_users,OU=my_department,OU=company",
'group',
{ Description => 'Users At My Department',
sAMAccountName => 'department_users',
GroupType => sprintf "%i",
( ADS_GROUP_TYPE_GLOBAL_GROUP |
ADS_GROUP_TYPE_SECURITY_ENABLED ) };
AD_add_object "CN=javerage,OU=my_department,OU=company",
'user',
{ sAMAccountName => 'javerage'
userPrincipalName => 'javerage@company.com',
FirstName => 'Joe',
FullName => 'Joe Average',
password => 'cleartext password',
AccountDisabled => 0, # not disabled
PasswordRequired => 1, # yes a password is required
LastName => 'Average',
AccountExpirationDate => '2040-12-31',
EmailAddress => 'joe@company.com',
Profile => '\\server\\home\\javerage\\profile',
HomeDirectory => '\\server\\home\\javerage',
homeDrive => 'W:', # mount home on drive W:
permpass => 1, # do not require a password change
};
AD_add_object "CN=compi,OU=my_department,OU=company",
'computer',
{ sAMAccountName => 'compi$',
netbootGUID => mac2guid('00:01:02:a9:d9:1c{01234567-89AB-CDEF-0123456789ABCDEF}'),
netbootInitialization =>
'\\\\server\REMINST\Setup\English\IMAGES\win2000.pro',
userAccountControl =>
sprintf("%i", (ADS_UF_WORKSTATION_TRUST_ACCOUNT))
};
my $arry_ref = AD_enumerate "LDAP://OU=my_department,OU=company",'computer';
my $arry_ref = AD_enumerate "LDAP://OU=my_department,OU=company",'user';
AD_remove_object "LDAP://CN=my_box,OU=my_department,OU=company",'computer';
The ActiveDirectory module provides a simple interface for adding new
Users, Groups and Computers to the Active Directory. The property
names are mostly the ones known from the ADSI documentation:
http://msdn.microsoft.com/library/psdk/adsi/ds2_ref_2x45.htm
Note that creating a user in the active directory alone is not
sufficient, you also have to create a home directory for the user and
set the proper permissions. When creating users from the Management
Console, this task gets performed automagically but this is not the
case for accounts created through the ADSI interface. We use
Win32::Perms http://www.roth.net/perl/perms/ from Roth consulting
for this task:
use Win32::Perms;
my $user = 'peter';
my $home = '\\\\server\\home\\'.$user;
mkdir $home;
my $dir = new Win32::Perms($home) or
die "ERROR: Faild to get Perm Object from $home";
$dir->Remove(-1); # remove defaults
$dir->Allow('Administrators',FULL,FILE);
$dir->Allow('Administrators',FULL,DIR);
$dir->Allow($user,FULL,FILE);
$dir->Allow($user,FULL,DIR);
$dir->Owner($user);
$dir->Set() or die "ERROR: Failed to set Permissions on $home";
$dir->Close();

use ISG::Win32::ActiveDirectory qw(AD_enumerate);
my $list = AD_enumerate "LDAP://OU=my_ou,OU=big_ou,DC=my_domain",'computer';
print join "\n", @$list;
| 2001-04-30 | to | Added POD Documentation | | 2001-07-11 | to | Fixed use statement documentation | | 2003-05-12 | to | Added AD_enumerate | | 2003-05-12 | to | Added AD_remove_object | | 2003-09-09 | to | Added wireguid to mac2guid convertor | | 2004-06-22 | ds | Return true if object was created | | 2005-06-23 | ma | allow for passing undef values to delete properties |
|