c.m.hurley has asked for the wisdom of the Perl Monks concerning the following question:

I use Perl on Microsoft Windows Server 2003

Perl version:

This is perl, v5.8.8 built for MSWin32-x86-multi-thread Binary build 819 267479 provided by ActiveState http://www.ActiveState.com Built Aug 29 2006 12:42:41

I want Perl to automate tasks with Active Directory Users and Computers.

I'm currently frustrated with errors coming from code samples in Perl from a code copied from Active Directory Cookbook by Robbie Allen.

I've studied the Perl code and tried several modifications. I've tested the VB version and that works on our system correctly.

If you want to review the VBS, the link is here. http://techtasks.com/code/viewbookcode/1585

Following is the code:

# --------------------------------------------------------------- # Adapted from VBScript code contained in the book: # "Active Directory Cookbook" by Robbie Allen # ISBN: 0-596-00466-4 # --------------------------------------------------------------- # ------ SCRIPT CONFIGURATION ------ my $strUserDN = "<UserDN>"; # e.g. cn=jsmith,cn=Users,dc=rallencorp,d +c=com # ------ END CONFIGURATION --------- use Win32::OLE 'in'; $Win32::OLE::Warn = 3; my $objUser = Win32::OLE->GetObject("LDAP://" . $strUserDN); print "Group membership for ", $objUser->Get("cn"), ":\n"; my $strSpaces = ""; my %dicSeenGroup; DisplayGroups("LDAP://$strUserDN", $strSpaces, %dicSeenGroup); sub DisplayGroups { my ($strObjectADsPath, $strSpaces, %dicSeenGroup) = @_; my $objObject = Win32::OLE->GetObject($strObjectADsPath); print $strSpaces, $objObject->Name,"\n"; if ($objObject->Get("memberOf")) { $colGroups = $objObject->Get("memberOf"); } foreach my $strGroupDN (in $colGroups) { if (not $dicSeenGroup{$strGroupDN}) { $dicSeenGroup{$strGroupDN} = 1; DisplayGroups("LDAP://" . $strGroupDN, $strSpaces . " ", %dic +SeenGroup); } } }

My own paranoia is not displaying the fully qualified domain name or uniform naming convention data for this user on our system

The output of this code looks like this:

C:\mysource\perl>perl enum-account-groups.pl Group membership for hurl9594: cn=hurl9594 CN=No_Local_Logon OLE exception from "Active Directory": The directory property cannot be found in the cache. Win32::OLE(0.1603) error 0x8000500d in METHOD/PROPERTYGET "Get" at enum-account-groups.pl line 32

This user has three groups assigned to them. The group after the 'CN' in the output is one of them.

I have Googled this error code. The results were not clear. I'm not sure whether I need to update a perl module, add a module or what?

I really want to do this work in Perl. Once I can read what groups a user is a member of, I will have to work on changing the group memberships with scripts.

Hopefully someone here will be able to refer me to a solution.

Thanks.

Replies are listed 'Best First'.
Re: Enumerate MS AD Group Membership
by eric256 (Parson) on Feb 24, 2007 at 00:26 UTC

    I can't help with your script, but I can provide you with one i use. This lists all users in an Everyone OU

    my $ldap = Net::LDAP->new('lucille.domain.com') or die ; # params for Net::LDAP::new # bind to a directory with dn and password my $mesg = $ldap->bind( 'ad_user', password => '******' ); my $fields = ['displayName','memberOf']; my $result = $ldap->search ( base => "ou=Everyone,dc=domainname,dc=com", filter => '(cn=*)', attrs => $fields, ); for my $item ( $result->entries) { next unless defined $item->get_value("displayName"); my $user; $user->{groups} = [ ref ( $item->get_value('memberOf') ) ? @{$item->get_value('memberOf')} : ($item->get_value('memberOf')) ]; $user->{groups} = [ map { /CN=(.+?),/ ; $1 } @{$user->{groups}} ]; print '"',$item->get_value("displayName"),'",'; print join(",", map { '"' . $_ . '"' } sort @{$user->{groups}} +),"\n"; }

    This logs in to LDAP and generates a CSV file with each members display name and then a list of their groups.


    ___________
    Eric Hodges
Re: Enumerate MS AD Group Membership
by idsfa (Vicar) on Feb 23, 2007 at 20:43 UTC

    Updated: <struck> Never let a unix guy answer a win question.

    Updated: Perhaps you wanted this example? (Which apparently partially exonerates my original comments ... so I'm going to </strike>)


    foreach my $strGroupDN (in $colGroups)

    Is not perl. Specifically, your $colGroups is not an array. Without digging into the guts of the Get method, I'll hazard that it is returning a reference to an array of strings. I think you want:

    foreach my $strGroupDN (@{$colGroups})

    The intelligent reader will judge for himself. Without examining the facts fully and fairly, there is no way of knowing whether vox populi is really vox dei, or merely vox asinorum. — Cyrus H. Gordon
Re: Enumerate MS AD Group Membership
by shonorio (Hermit) on Feb 24, 2007 at 12:19 UTC
Re: Enumerate MS AD Group Membership
by c.m.hurley (Novice) on Feb 26, 2007 at 17:22 UTC

    Thanks for all the comments and code samples.

    For those interested, the one that works in our environment is the post by eric256. I did have to add a 'uses' clause to make the snippet return data.