I'm trying to create a Perl script that obtains user and workstation information from Active Directory (AD). Are you aware of any Perl functions or modules to manage AD? A sample script would also help.
Your options depend on the platform on which you're running the script and on how portable you want the script to be. Your options include using Win32::OLE with Microsoft Active Directory Service Interfaces (ADSI), Net::LDAP, Mozilla::LDAP, and Lightweight Directory Access Protocol (LDAP) Data Interchange Format Data Exchange (LDIFDE).
Win32::OLE with ADSI. If you're running your script on a Windows platform, you can use the Win32::OLE module combined with ADSI. Win32:: OLE lets you use COM-based libraries and components (also known as OLE automation) with Perl. ADSI is Microsoft's primary set of COM-based interfaces to programmatically manage AD. Although using Win32::OLE with ADSI is the least portable solution, it's perhaps the most comprehensive and easiest to use because Microsoft designed ADSI primarily for AD.
Net::LDAP. If portability is your primary concern, you can use Graham Barr's perl-ldap distribution. This collection of Perl modules, which includes Net::LDAP, lets you manage LDAP directories such as AD. To learn more about Net::LDAP, see the Perl-LDAP Homepage (http://perl-ldap.sourceforge.net) or "Querying and Updating AD, Part 1," February 2003, http://www.winscriptingsolutions.com, InstantDoc ID 27569, and "Querying and Updating AD, Part 2," March 2003, InstantDoc ID 37717.
Mozilla::LDAP. Another option is the Mozilla::LDAP module, also known as PerLDAP. Scripts that use Mozilla::LDAP aren't as portable as scripts that use Net::LDAP because Mozilla::LDAP has a dependency on the Netscape LDAP APIs. For more information about Mozilla::LDAP, see the PerLDAP Web site (http://www.perldap.org).
LDIFDE. You can use many command-line tools to manage AD with Perl. One of the most popular tools is the LDIFDE utility (ldifde.exe), which you can find in the %systemroot%\system32\ directory. LDIFDE uses text-based input files to import and export data to and from AD, which makes it well suited for Perl scripts if you don't mind spawning another process. To learn more about LDIFDE, see the Windows 2000 Server Help topic Importing and exporting directory information.
Listing 1 contains a sample script that demonstrates how to use Win32::OLE with ADSI to manage AD. I created and tested the script on a machine running Windows Server 2003, Enterprise Edition Release Candidate 1 (RC1) and ActiveState's ActivePerl 5.6.1, build 633. The script demonstrates all the major steps in managing the life cycle of an AD object—an AD user account object in this case. The script binds to a container in the directory, creates a user object named Tim Towtdi, writes attributes to the newly created object, reads those attributes, and deletes the object.
Let's take a closer look at how the script works. In the first line, I import the Win32::OLE module, which I need to connect to AD and call ADSI methods. I then initialize the scalar variable named $adspath with the mandatory and case-sensitive ADSI moniker, LDAP:, followed by the distinguished name (DN) of the target AD container (or object). You'll need to change the DN portion of the value assigned to $adspath to run the script in your domain. Next, I use $adspath and Win32::OLE's GetObject method to connect to AD, a process known as binding in LDAP terminology. GetObject returns a reference to the target container that I can now use to call ADSI methods.
The first ADSI method I call is ADSI's Create method, as the code at callout A in Listing 1 shows. This method takes two parameters: the type (i.e., class) of object to create as defined in the AD schema and the new object's relative DN (RDN). The Create method returns a reference to the newly created object, which I subsequently use to perform additional operations on the new object. I should point out that the new user object doesn't exist in AD yet. Instead, the new object is locally cached until I use ADSI's SetInfo method to commit the object to AD. Before I can commit the new object to the directory, I must set any mandatory attributes that the system doesn't set. AD user objects have one mandatory attribute named sAMAccountName, which I set by using ADSI's Put method. The SetInfo method then writes the object to the target container in AD.
With the new user object persisted in the directory, I can use ADSI's SetPassword method to assign the user a password, as the code at callout B shows. Notice that I don't call SetInfo to commit the password. The SetPassword method writes the new password directly to the object in the directory. (The same is true for changing a password with ADSI's ChangePassword method.) Now that the user has a password, I use ADSI's AccountDisabled property to enable the account, as the code after callout B shows.
The code at callout C sets the 11 attributes that appear on the user's General Properties page as viewed in the Microsoft Management Console (MMC) Active Directory Users and Computers snap-in. I use the Put method to write the attributes' values. This method takes two parameters: the lDAPDisplayName of the attribute to set and the attribute's value. The values are locally cached until I call the SetInfo method.
The script then reads and displays the 11 attributes, as the code at callout D shows. I use ADSI's GetInfo method to populate the local cache with the attributes' values and ADSI's Get method to fetch a specific value from the cache. After I direct the attributes to the console for display, I use ADSI's Delete method to delete the user object. Like the Create method, the Delete method takes two parameters: the type (i.e., class) of object to delete and the object's RDN.
So where can you learn more about how to use ADSI and the Win32::OLE module to manage AD? To start, I encourage you to read "Using OLE with Perl" in the ActivePerl User Guide (http://aspn.activestate.com/ASPN/Products/ActivePerl/faq/Windows/ActivePerl-Winfaq12.html). You should also check out the Active Directory, ADSI and Directory Services documentation in the Microsoft Developer Network (MSDN) Library (http://msdn.microsoft.com/nhp/default.asp?contentid=28000413).
Beyond reading each technology's documentation, I recommend that you read David N. Blank-Edelman's Perl for System Administration (O'Reilly & Associates, 2000). In Chapter 6, "Directory Services," the author devotes about 20 pages to using Win32::OLE with ADSI. You can download sample scripts from the book for free at http://examples.oreilly.com/perlsysadm. The book also covers the Net::LDAP and Mozilla::LDAP modules.
You should also check out Toby Everett's ADSI and Perl information at http://public.activestate.com/authors/tobyeverett/index.html. Although the information is somewhat dated, Everett created a graphical ADSI browser written entirely in Perl/Tk. This browser is a great tool for learning how to use ADSI with Perl.