Help with Adding Multiple users to Groups...

Answered Help with Adding Multiple users to Groups...

  • Friday, June 15, 2012 4:40 PM
     
      Has Code

    I am working with a powershell script, to add users to groups based off a CSV I am loading. And I am having a hard time making it work. Here is the issue

    1. I have built the CSV - And I have the script ready to roll. Right Now I only have one user, but when it is all said and done, we will have 2400 users (so I would rather not do it by hand)

    2. The Active Directory it's self is managed by The Campus IT Department, and because it is a bit large (This is a large University with about 35,000 active users in AD) it takes a while to respond to scripts. 

    3. The OU where my users are located is "OU=People,DC=ad,DC=<university>,DC=edu

    4. The OU where my Groups are located is "OU,Security Groups,OU=Business,OU=Department OUs,DC=ad,DC=<university>,DC=edu"

    Here is the script I am using: (The Highlighted Section is where I bomb)

    #Lets Load up the CSV File into Memory and Get Ready to Rock!
    $UserGroups = Import-Csv -Path "C:\scripts\usr_groups_defined.csv"
    
    #Hash the table of Group Objects from AD
    $List = @{}
    
    ForEach ($Line In $UserGroups)
    {
    	
    	#Retieve values we have defined for this user.
    	$DN = $Line.DN
    	$MemberOfCollection = $Line.MemberOf -split ';'
    	#Loop through each line
    	ForEach ($MemberOf in $MemberOfCollection)
    	{
    		#We Need to Check to ensure users arent being added twice to the group.
    		If ($List.ContainsKey($MemberOf))
    		{
    			#Use Previous object reference.
    			$Group = $List[$MemberOf]
    		}
    		Else
    		{
    			#Bind to the Group Object, and save our reference in the hash table.
    			$Group = [ADSI]"LDAP://$DN" #Define the Base OU where Groups live
    			$List[$MemberOf] = $Group
    		}
    		#Check to ensure user is not already a member of the group we are trying to add them to.
    		If($Group.IsMember("LDAP://$DN") -eq $False)
    		{
    			#Add the user to the group
    			$Group.Add("LDAP://$DN")
    		}
    	}
    }


    When I search for my User in the Directory in LDAP Using [ADSI]"LDAP://CN=<userID>,OU=People,DC=ad,DC=<university>,DC=edu"

    I Get a response from AD like this:

    distinguishedName : {CN=<userID>,OU=People,DC=ad,DC=<university>,DC=edu}
    Path              : LDAP://CN=<userID>,OU=People,DC=ad,DC=<university>,DC=edu

    When I query for one of the groups I am trying to add the user to AD Responds with

    PS C:\scripts>  [ADSI]"LDAP://cn=BUS-SG-ITGroup,OU=Security Groups,OU=Business,OU=Department OUs,DC=ad,DC=<university>,DC=edu"


    distinguishedName : {CN=BUS-SG-ITGroup,OU=Security Groups,OU=Business,OU=Department OUs,DC=ad,DC=<university>,DC=edu}
    Path              : LDAP://cn=BUS-SG-ITGroup,OU=Security Groups,OU=Business,OU=Department OUs,DC=ad,DC=<university>,DC=edu


    Any help, or tips as to where i am going wrong would be greatly appreciated.

    Thanks.

All Replies

  • Friday, June 15, 2012 4:54 PM
    Moderator
     
      Has Code

    Just a quick glance, but you seem to be using $DN as the DN of the group and of the new member. Seems like the DN of the group should be $MemberOf. This statement looks wrong:

    $Group = [ADSI]"LDAP://$DN"

    and probably should be:

    $Group = [ADSI]"LDAP://$MemberOf"


    Richard Mueller - MVP Directory Services

  • Friday, June 15, 2012 5:02 PM
     
      Has Code

    Thank you, Now that I have made that change, I get this error: (So I think I am making Progress)

    The following exception occurred while retrieving member "IsMember": "The server is not operational.
    "
    At C:\scripts\usergrp.ps1:37 char:5
    +         If <<<< ($Group.IsMember("LDAP://$DN") -eq $False)
        + CategoryInfo          : NotSpecified: (:) [], ExtendedTypeSystemException
        + FullyQualifiedErrorId : CatchFromBaseGetMember
    
    The following exception occurred while retrieving member "IsMember": "Unknown error (0x80005000)"
    At C:\scripts\usergrp.ps1:37 char:5
    +         If <<<< ($Group.IsMember("LDAP://$DN") -eq $False)
        + CategoryInfo          : NotSpecified: (:) [], ExtendedTypeSystemException
        + FullyQualifiedErrorId : CatchFromBaseGetMember

    It seems like the Script is expecting a faster response than the Directory can provide - is there a way to 

    1. Specify the Domain (force it to look at "DC=ad,DC=Utah,DC=edu") as opposed to banging around for the Domain the computer I am running it from 

    or 

    2. Make it so the script runs longer before bombing?

  • Friday, June 15, 2012 5:18 PM
    Moderator
     
      Has Code

    As written, the script assumes that the file contains the full Distinguished Names of users and groups. For example, I tested with this csv file:

    "DN","MemberOf"
    "cn=test user,ou=West,dc=MyDomain,dc=com","cn=Test1,ou=East,dc=MyDomain,dc=com;cn=Test2,ou=East,dc=MyDomain,dc=com"

    Note that all values (two values per line) are enclosed in quotes (because they contain embedded commas), and the MemberOf field has more than one DN value delimited by a semicolon.

    I suspect from the comment in the script that your group DN's are not complete, but assume some "Parent" OU. Each $MemberOf value must be a full group distinguished name. If not, you must concatenate the rest of the DN in the script.


    Richard Mueller - MVP Directory Services

  • Friday, June 15, 2012 5:47 PM
     
      Has Code

    Here is the CSV File I am using. 

    "DN","memberOf"
    "CN=<userid>,OU=People,DC=ad,DC=<university>,DC=edu","CN=BUS-SG-ITGroup,OU=Security Groups,OU=Business,OU=Department OUs,DC=ad,DC=<university>,DC=edu;
    CN=BUS-SG-LocalAdmins,OU=Security Groups,OU=Business,OU=Department OUs,DC=ad,DC=<university>,DC=edu;
    CN=BUS-SG-Staff,OU=Security Groups,OU=Business,OU=Department OUs,DC=ad,DC=<university>,DC=edu;CN=BUS-SG-VPN,OU=Security Groups,OU=Business,OU=Department OUs,DC=ad,DC=<university>,DC=edu;
    =CN=BUS-SG-All_Users,OU=Security Groups,OU=Business,OU=Department OUs,DC=ad,DC=<university>,DC=edu"

    So I guess my question is how to i define the OU where all my groups I am working with are within the script? And just have it add to the groups Under that OU that I specify within the CSV or do I need to have the FQN of the Group, Child OU, Child OU, Child Ou, Parent OU, Domain



    • Edited by Smitty K_ Friday, June 15, 2012 5:51 PM
    • Edited by Smitty K_ Friday, June 15, 2012 5:52 PM
    •  
  • Friday, June 15, 2012 6:08 PM
    Moderator
     
     

    Your distinguished names specify where in AD the group objects reside. No other information required.

    Looking at the error messages, it seems that "LDAP://$DN" is invalid. Is it possible that <userid> is the sAMAccountName (pre-Windows 2000 logon name) of the user instead of the Common Name (the value of the cn attribute)? I believe that the $MemberOf value is good, as it seems that the IsMember method is recognized, so we know that $Group refers to a valid group object in AD.

    Also, if the Common Name of the user includes the comma character, it must be escaped with the backslash escape character , "\".


    Richard Mueller - MVP Directory Services

  • Friday, June 15, 2012 6:29 PM
     
      Has Code

    So it throws this error: 

    The following exception occurred while retrieving member "IsMember": "Unknown error (0x80005000)"
    At C:\scripts\usergrp.ps1:37 char:5
    +         If <<<< ($Group.IsMember("LDAP://$DN") -eq $False)
        + CategoryInfo          : NotSpecified: (:) [], ExtendedTypeSystemException
        + FullyQualifiedErrorId : CatchFromBaseGetMember

    And then adds me to the group. 

    (I tested it 3 times) 


  • Friday, June 15, 2012 8:39 PM
    Moderator
     
     Answered Has Code

    I just tried the script and it worked for me. The version I used follows:

    $UserGroups = Import-Csv -Path "C:\PowerShell\usr_groups_defined.csv"

    #Hash the table of Group Objects from AD
    $List = @{}

    ForEach ($Line In $UserGroups)
    {
        
        #Retieve values we have defined for this user.
        $DN = $Line.DN
        $MemberOfCollection = $Line.MemberOf -split ';'
        #Loop through each line
        ForEach ($MemberOf in $MemberOfCollection)
        {
            #We Need to Check to ensure users arent being added twice to the group.
            If ($List.ContainsKey($MemberOf))
            {
                #Use Previous object reference.
                $Group = $List[$MemberOf]
            }
            Else
            {
                #Bind to the Group Object, and save our reference in the hash table.
                $Group = [ADSI]"LDAP://$MemberOf"
                $List[$MemberOf] = $Group
            }
            #Check to ensure user is not already a member of the group we are trying to add them to.
            If($Group.IsMember("LDAP://$DN") -eq $False)
            {
                #Add the user to the group
                $Group.Add("LDAP://$DN")
            }
        }
    }

    -----



    Richard Mueller - MVP Directory Services

  • Friday, June 15, 2012 9:13 PM
     
     

    Well it still ads me, I guess I am just wondering why it is bombing even when it adds me to the group. 

    How can i tell if the error is coming from the Directory or if it is a problem with the script?

    (Sorry for all the n00b questions, but i am just getting a grasp on powershell scripting)

  • Saturday, June 16, 2012 2:13 AM
    Moderator
     
     

    I get the the error you report if I specify an incorrect group distinguished name (DN) in the csv file. If the group DN is correct, the IsMember method works without error, even if the same group DN is used on subsequent lines (so the object reference is retrieved from the hash table).


    Richard Mueller - MVP Directory Services