Hey, Scripting Guy! I need to “clone” a local group; in other words, I want to create a new group that contains the same members as the original group. However, I can’t find any sort of copy command that would let me do this. How can I copy the membership of a local group to a new local group?
Hey, SO. Before we begin, we should take a moment to note that the 2008 Winter Scripting Games are now less than two months away; the games begin on Friday, February 15, 2008 and end on Monday, March 3, 2008. Does that matter to you? Well, it should: after all, with the possible exception of the Super Bowl, the Scripting Games are the biggest and most important competition to take place anywhere in the world over the next two months. And while the NFL is really picky about who does, and does not, get to play in the Super Bowl, the Scripting Games are open to anyone and everyone. Are you a beginning scripter? No problem; we have a Beginners Division which features events aimed at scripting newcomers. Are you a more experienced scripter? No problem; we have an Advanced Division in which you can test your mettle against the best scripters in the world. See? Something for everyone.
As for languages, well, this time around we’re offering competition in VBScript, Windows PowerShell, and Perl. Enter one competition or enter all six competitions; it makes no difference to us. And don’t worry, there’s no entry fee and no pre-registration; just show up at the Games home page on February 15th and have at it. (Try showing up at the Super Bowl with 11 of your friends and see if they’ll let you play. Good luck on that one.)
Anyway, we hope to see everyone on February 15th. The Scripting Games are fun, they’re (gasp!) educational, and they are well worth the effort. Most important, if you enter at least one event then no one will make fun of you for being too much of a chicken to enter the Games.
Note. Will people really make fun of you if you don’t enter the Games? Well, they will if we have anything to say about it. Baawk, baawk, baawk!
Disclaimer. The Scripting Editor has just informed us that it’s not Microsoft policy to make fun of other people; that it is not Microsoft policy to encourage anyone else to make fun of other people; and that it is not Microsoft policy to make chicken-like noises when writing a daily scripting column. To tell you the truth, that’s hard for us to believe; after all, Microsoft has a reputation for being such a happy-go-lucky, fun-loving sort of place. Tell you what: hold off on making fun of anyone for now, and the next time the Scripting Guy who writes this column meets with the HR department (something which happens on a very regular basis) he’ll ask them about that.
Unless, of course, the HR people are too chicken to talk to him about that. Baawk, baawk, baawk!
In the meantime, many of you are probably wondering what you can do to get ready for the Games. Well, for one thing, you can take a look at our weekly Scripting Games tips; it’s a sure bet that those tips will come in handy at some point in the competition. For another, you can continue reading this column, and learn how to copy the members of one local group to a new local group. Admittedly, that wouldn’t have helped you much last year, when the Scripting Games events included such tasks as writing a script that could test someone for extra-sensory perception or a script that could play a game of jacks. But hey, maybe this year’s Games will include an event on copying the members of one local group to a new local group. When it comes to the Scripting Games, you never know.
Unless, of course, you’re too chicken to keep reading this column. Baawk, baawk, baawk!
Sorry. Once you start with that it’s hard to stop.
Let’s kick things off by taking a look at how we can “clone” a group on the same computer (that is, both the original group and the new group reside on the same machine). After that, we’ll show you a script that – with some restrictions – can create the cloned group on a second computer.
But, first things first:
strComputer = "atl-fs-001" Set colAccounts = GetObject("WinNT://" & strComputer & "") Set objNewGroup = colAccounts.Create("group", "NewGroup") objNewGroup.SetInfo Set objGroup = GetObject("WinNT://" & strComputer & "/OldGroup") For Each strUser in objGroup.Members objNewGroup.Add(strUser.AdsPath) Next
As you can see, this is a relatively simple little script. We start out by assigning the name of the computer in question (that is, the computer where the original group resides) to a variable named strComputer. After we’ve done that we can then bind to the Security Accounts Manager (SAM) on that machine by using this line of code:
Set colAccounts = GetObject("WinNT://" & strComputer & "")
And once we’ve connected to the SAM we can create a new local group (a group cleverly-named NewGroup) by using the Create method and then calling the SetInfo method:
Set objNewGroup = colAccounts.Create("group", "NewGroup") objNewGroup.SetInfo
That gives us a new local group, albeit a new group that doesn’t have any members. Considering the fact that this new group is supposed to have the same members as an existing group (OldGroup), well, what exactly was the point of all that?
Believe it or not, there is a point to all that. As SO noted, he had difficulty locating a copy command that would copy the membership of one group to a new group. Why did he have so much difficulty locating the copy command? One reason might be this: there’s no such thing as the copy command. In fact, as far as we know, there’s no straightforward, one-command approach to cloning a local group and its membership. Instead, you need to do this: create the new group, then “manually” copy the membership list of the original group to this new group.
What does that mean? Coincidentally enough, we were just about to explain what that all means. Now that we have our new group our next step is to make a second connection, this one to the original group (OldGroup). That’s what this line of code is for:
Set objGroup = GetObject("WinNT://" & strComputer & "/OldGroup")
After we make the connection we then set up a For Each loop to walk through the values stored in the Members attribute; as the name implies, the Members attribute contains a list of all the group members. Notice that we’re looping through the values in the original group, the one with the object reference objGroup:
For Each strUser in objGroup.Members
Is that important? Of course it is. Remember, our new group (objNewGroup) doesn’t even have any members.
Well, not yet anyway.
So what do we do inside this loop? One thing and one thing only: we execute the following line of code:
All we’re doing here is using the Add method to add a new member to the cloned group (NewGroup). And just who are we adding to the group? You got it: the first member of the original group. We add this first member to NewGroup (using the user’s ADsPath attribute as the method parameter) and then loop around and repeat the process with the next member of the original group. When we’re all done, our two groups – NewGroup and OldGroup – will have the exact same members. Even though the copy command doesn’t exist we still managed to copy the membership of one group to another.
And that’s what it means to “manually” copy the membership list of one group to another.
Now, what about copying group membership from a local group on one computer to another local group on another computer? Can we even do that?
Yes, we can, although as we noted, there are some limitations here. The script we’re about to show you works just fine as long as a group member is a domain user; if a group member happens to be a local user, however, that user will not be copied to the new group. Why not? Well, suppose we have a computer named atl-fs-001, a computer that belongs to the fabrikam.com domain. A local user account on that machine is going to have an ADsPath similar to this:
The only way to add local user Ken Myer to a group on the computer atl-fs-002 would be to change Ken’s ADsPath to look like this:
Could you do that programmatically? Sure, but even then the script will fail if the user Ken Myer doesn’t exist on the remote machine. OK, but could you then check for the existence of that account and then create it if it doesn’t exist? Yes, but by then we’re way beyond what we can do in today’s column. If that’s of interest to people just let us know, and we’ll see if we can tackle that in the future.
For now, here’s a script that will copy any domain users who belong to the group OldGroup (on the computer atl-fs-001) to the membership list of the group NewGroup on atl-fs-002:
On Error Resume Next strComputer1 = "atl-fs-001" strComputer2 = "atl-fs-002" Set colAccounts = GetObject("WinNT://" & strComputer1 & "") Set objNewGroup = colAccounts.Create("group", "NewGroup") objNewGroup.SetInfo Set objGroup = GetObject("WinNT://" & strComputer2 & "/OldGroup") For Each strUser in objGroup.Members objNewGroup.Add(strUser.AdsPath) Next
Thanks to the On Error Resume Next command, the script will copy over any domain users, and simply ignore any local users. Which, like we said, is the best we can hope for without adding a bunch of extra code.
We had a feeling that would come up: many of you would now like to perform this same task with Active Directory groups. Again, we’re pretty much out of time for today. But this script, found in the Community Script Center, should help you do that.
We hope that helps, SO. Incidentally, if you, or anyone else out there is still waffling on whether or not they should enter the Scripting Games (did someone say, “Baawk, baawk, baawk?”), well, consider this: we have some fantastic prizes lined up for this year’s Games. We can’t give you the details just yet; however, we can tell you that anyone who scores at least 60 points (out of 100) in any division will receive one of the coveted Certificates of Excellence. We can also tell you that there will be a brand-new Dr. Scripto bobblehead, one designed especially for the Scripting Games. Oh, and we’ll have script editors and other cool software to give away as well. (Details to come.)
And yes, we know that none of you need to be bribed by the prospect of prizes in order to enter the Games; after all, you want to enter just for the sheer joy of taking part. But you might mention these prizes to any of your ... friends … who might still need convincing. The Scripting Guys are definitely not above bribing people any time we can.
Unless, of course, you’re too chicken to take a bribe. Baawk, baa – well, you know the rest.
Note. You might also tell your … friends … that they’ll be eligible to win any of these prizes just by entering a single event; they don’t even have to successfully complete that event to have a chance to win big. (Try doing that at the Super Bowl.) The only exception, of course, is the coveted Certificate of Excellence; that one you have to earn. Which helps explain why it’s the coveted Certificate of Excellence.