How Can I Change a User’s Primary Group?

How Can I Change a User’s Primary Group?

  • Comments 3
  • Likes
Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I change a user’s primary group?

-- AS

SpacerHey, Scripting Guy! AnswerScript Center

Hey, AS. You know, one of the Scripting Guys knows how to make an incredibly rich rocky road brownie, a brownie that’s topped with melted marshmallows and walnuts and chunks of dark chocolate and all sorts of other good stuff. Now, some people might ask whether or not, in the interests of promoting a healthy lifestyle, this Scripting Guy should make such a decadent dessert. But you know what? The Scripting Guys are doers, not thinkers: we’ll continue making brownies, and we’ll let others debate whether or not that’s really what we should be doing.

Hold on a second: we need to cut ourselves another brownie. Just a small one this time ….

The same thing is true of changing a user’s primary group: we know how to do it, but we don’t know whether or not you should do it. According to what little we know about Active Directory, the primary group is used only if you have to deal with Macintosh clients or POSIX-compliant applications; otherwise, you can just leave the primary group alone. (By default, the primary group for each user is Domain Users.) That means, for most people, you can probably file today’s column under Things I Don’t Need to Worry About, At Least Not Today. Most of you will be able to lead long and happy lives without ever changing a user’s primary group. (Yes, hard to believe. But true.)

But suppose you do need to change a user’s primary group. In that case, here’s a script that will take care of everything for you:

Set objUser = GetObject _
    ("LDAP://cn=Ken Myer,ou=Finance,dc=fabrikam,dc=com")
 
Set objGroup = GetObject _
    ("LDAP://cn=Finance Managers,ou=Finance,dc=fabrikam,dc=com")

objGroup.GetInfoEx Array("primaryGroupToken"), 0

objUser.primaryGroupID = objGroup.primaryGroupToken
objUser.SetInfo

The script begins by binding to the user account you want to modify; in this sample script, we bind to the Ken Myer account in the Finance OU of fabrikam.com. We then create a second object reference, this one to the group that will become the user’s new primary group (Finance Managers). Note that this script assumes that the user is already a member of the group Finance Managers. If that’s not the case then you will need to add the user to the group before Finance Managers can be reassigned as the primary group.

Next we use the GetInfoEx method to explicitly retrieve the value of the primaryGroupToken attribute for Finance Managers. The primaryGroupToken is a computed attribute used when retrieving the membership list for certain groups. Because this is a computed attribute - that is, the value is generated on-the-fly rather than being stored as-is - we use GetInfoEx to force this computation and return the value. The GetInfoEx code looks like this:

objGroup.GetInfoEx Array("primaryGroupToken"), 0

While we’re on the subject, we should point out a few quirks regarding GetInfoEx. First, GetInfoEx always retrieves data as though it was stored as an array; hence the need to specify an array consisting of a single item (primaryGroupToken). The 0 tacked on the end of the call is meaningless but required: if you leave it off or if you substitute a different value, the script will fail.

To be honest, we don’t know why; that’s just the way it works.

The rest is easy. We set the value of the primaryGroupID to the primaryGroupTaken value we just retrieved, and then call the SetInfo method to write those changes to the user account in Active Directory:

objUser.primaryGroupID = objGroup.primaryGroupToken
objUser.SetInfo

That should do the trick. As we noted, by default all users are assigned Domain Users as their primary group. If you ever want to switch Ken Myer back to this default then simply run this script, which changes the primary group back to Domain Users:

Set objUser = GetObject _
    ("LDAP://cn=Ken Myer,ou=Finance,dc=fabrikam,dc=com")
 
Set objGroup = GetObject _
    ("LDAP://cn=Domain Users,cn=Users,dc=fabrikam,dc=com")

objGroup.GetInfoEx Array("primaryGroupToken"), 0

objUser.primaryGroupID = objGroup.primaryGroupToken
objUser.SetInfo

That’s all you need to do. As for us, we’re going to cut ourselves another brownie. Just a small one this time ….

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • I really like to coding within the framework of patience and very good ones you do something I have been told in

  • Hello, Thank you for sharing with us this script. I've have a little problem trying it, here is what i got..... >> Running (move old users.ps1) Script... >> Platform: 32Bit (STA) ERROR: GetInfoEx : The following exception occurred while retrieving member "GetInfoEx": "There is no such object on the server. ERROR: " ERROR: move old users.ps1 (40): ERROR: At Line: 40 char: 20 ERROR: + $OldGroup.GetInfoEx <<<< (@("primaryGroupToken"), 0) ERROR: + CategoryInfo : NotSpecified: (:) [], ExtendedTypeSystemException ERROR: + FullyQualifiedErrorId : CatchFromBaseGetMember ERROR: ERROR: = : The following exception occurred while retrieving member "Get": "There is no such object on the server. ERROR: " ERROR: move old users.ps1 (41): ERROR: At Line: 41 char: 17 ERROR: + $OldGroupToken = <<<< $OldGroup.Get("primaryGroupToken") ERROR: + CategoryInfo : NotSpecified: (:) [], ExtendedTypeSystemException ERROR: + FullyQualifiedErrorId : CatchFromBaseGetMember ERROR: ERROR: GetInfoEx : The following exception occurred while retrieving member "GetInfoEx": "There is no such object on the server. ERROR: " ERROR: move old users.ps1 (44): ERROR: At Line: 44 char: 20 ERROR: + $NewGroup.GetInfoEx <<<< (@("primaryGroupToken"), 0) ERROR: + CategoryInfo : NotSpecified: (:) [], ExtendedTypeSystemException ERROR: + FullyQualifiedErrorId : CatchFromBaseGetMember ERROR: ERROR: = : The following exception occurred while retrieving member "Get": "There is no such object on the server. ERROR: " ERROR: move old users.ps1 (45): ERROR: At Line: 45 char: 17 ERROR: + $NewGroupToken = <<<< $NewGroup.Get("primaryGroupToken") ERROR: + CategoryInfo : NotSpecified: (:) [], ExtendedTypeSystemException ERROR: + FullyQualifiedErrorId : CatchFromBaseGetMember ERROR: ERROR: : An error occurred while enumerating through a collection: The (&(objectClass=user)(objectCategory=person)(primaryGroupId=)) search filter is inval ERROR: id.. ERROR: move old users.ps1 (58): ERROR: At Line: 58 char: 1 ERROR: + <<<< $Searcher.FindAll() | %{ ERROR: + CategoryInfo : InvalidOperation: (System.Director...sultsEnumerator:ResultsEnumerator) [], RuntimeException ERROR: + FullyQualifiedErrorId : BadEnumeration ERROR: >> Execution time: 00:00:05 >> Script Ended Do you have any idea ?

  • Hello, Thank you for sharing with us this script. I've have a little problem trying it, here is what i got..... >> Running (move old users.ps1) Script... >> Platform: 32Bit (STA) ERROR: GetInfoEx : The following exception occurred while retrieving member "GetInfoEx": "There is no such object on the server. ERROR: " ERROR: move old users.ps1 (40): ERROR: At Line: 40 char: 20 ERROR: + $OldGroup.GetInfoEx <<<< (@("primaryGroupToken"), 0) ERROR: + CategoryInfo : NotSpecified: (:) [], ExtendedTypeSystemException ERROR: + FullyQualifiedErrorId : CatchFromBaseGetMember ERROR: ERROR: = : The following exception occurred while retrieving member "Get": "There is no such object on the server. ERROR: " ERROR: move old users.ps1 (41): ERROR: At Line: 41 char: 17 ERROR: + $OldGroupToken = <<<< $OldGroup.Get("primaryGroupToken") ERROR: + CategoryInfo : NotSpecified: (:) [], ExtendedTypeSystemException ERROR: + FullyQualifiedErrorId : CatchFromBaseGetMember ERROR: ERROR: GetInfoEx : The following exception occurred while retrieving member "GetInfoEx": "There is no such object on the server. ERROR: " ERROR: move old users.ps1 (44): ERROR: At Line: 44 char: 20 ERROR: + $NewGroup.GetInfoEx <<<< (@("primaryGroupToken"), 0) ERROR: + CategoryInfo : NotSpecified: (:) [], ExtendedTypeSystemException ERROR: + FullyQualifiedErrorId : CatchFromBaseGetMember ERROR: ERROR: = : The following exception occurred while retrieving member "Get": "There is no such object on the server. ERROR: " ERROR: move old users.ps1 (45): ERROR: At Line: 45 char: 17 ERROR: + $NewGroupToken = <<<< $NewGroup.Get("primaryGroupToken") ERROR: + CategoryInfo : NotSpecified: (:) [], ExtendedTypeSystemException ERROR: + FullyQualifiedErrorId : CatchFromBaseGetMember ERROR: ERROR: : An error occurred while enumerating through a collection: The (&(objectClass=user)(objectCategory=person)(primaryGroupId=)) search filter is inval ERROR: id.. ERROR: move old users.ps1 (58): ERROR: At Line: 58 char: 1 ERROR: + <<<< $Searcher.FindAll() | %{ ERROR: + CategoryInfo : InvalidOperation: (System.Director...sultsEnumerator:ResultsEnumerator) [], RuntimeException ERROR: + FullyQualifiedErrorId : BadEnumeration ERROR: >> Execution time: 00:00:05 >> Script Ended Do you have any idea ?