Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I list all the groups in a Windows NT 4.0 domain?

-- MN

SpacerHey, Scripting Guy! AnswerScript Center

Hey, MN. It’s Martin Luther King, Jr. Day here in the USA, and, normally, you’d expect the Scripting Guy who writes this column to start things off by relating some irrelevant anecdote about Dr. King. Oddly enough, however, the Scripting Guy who writes this column, while fairly well-versed with the history of the civil rights movement, doesn’t have any anecdotes about Martin Luther King, Jr. But don’t worry: fortunately he does have a couple of anecdotes about Martin Luther, instigator of the Protestant Reformation.

We hear you: that was a close one, wasn’t it? After all, without those Martin Luther anecdotes this daily scripting column would have been reduced to talking about scripting. Perish the thought!

But enough chitchat; we have interesting anecdotes to relate. For one, Luther is perhaps best known for the statement he made at the Diet of Worms: “Here I stand; I can do no otherwise.” What’s so interesting about that? Apparently, he didn’t actually say it; instead, that statement was tacked on to his actual speech by a later biographer.

Hopefully some future biographer will go through all the Hey, Scripting Guy! columns and attach suitably profound statements to each one of those.

Here’s another interesting anecdote. Although Luther often railed against superstition, he still believed that he was hounded by the Devil. In fact, on one occasion he threw a shoe at Lucifer, something which managed to, at least temporarily, chase the Devil away.

Note. Sure, that’s does sound like a good piece advice: if you find yourself hounded by the Devil just throw a shoe at him. To be honest, though, most of you will never actually see the Devil. Unlike, say, those of us who work at Microsoft.

Wait, wait; take it easy. If you’re thinking, “I knew it, I knew the Devil worked at Microsoft,” well, we have to burst your bubble: we were just joking. The Devil does not work at Microsoft.

He has enough problems as it is.

Now that we have our anecdotes out of the way let’s focus on the business at hand: listing all the groups in a Windows NT 4.0 domain. It’s hard to believe that, after nearly 700 Hey, Scripting Guy! columns we’ve never addressed this issue. But, now we have:

strDomain = "fabrikam"

Set colGroups = GetObject("WinNT://" & strDomain & "")
colGroups.Filter = Array("group")

For Each objGroup In colGroups
    Wscript.Echo objGroup.Name 
Next

Man, if we’d known it was this easy to list all the groups in a Windows NT 4.0 domain we would have written this script a long time ago!

As you can see, we really don’t have to do much here. We start out by assigning the name of the domain (fabrikam) to a variable named strDomain. We then use the WinNT provider to bind to the domain. Pay close attention to the odd letter casing here: WinNT. ADSI provider names are case-sensitive; that means that winnt or WINNT or anything other than WinNT will cause the script to fail.

Binding to the domain gives us a collection of all the domain objects, including users, groups, printers, and what-have-you. Because we’re interested only in groups we next apply a Filter that limits returned data to, well, groups:

colGroups.Filter = Array("group")

And, yes, we do need to pass the Filter value (group) as an array, even though there’s just one item for this particular filter. For such a little script it’s just jam-packed with things you have to watch out for, isn’t it?

All that’s left at this point is to set up a For Each loop to loop through the collection and echo back the Name of each group:

For Each objGroup In colGroups
    Wscript.Echo objGroup.Name 
Next

What’s that? You say that, in addition to the name of each group, you’d like to see the membership for each of these groups? All you had to do was ask:

strDomain = "fabrikam"

Set colGroups = GetObject("WinNT://" & strDomain & "")
colGroups.Filter = Array("group")

For Each objGroup In colGroups
    Wscript.Echo objGroup.Name 
    For Each objUser in objGroup.Members
        Wscript.Echo objUser.Name
    Next
    Wscript.Echo
Next

Here’s another bonus: this same script, virtually unchanged, can also be used to return information about local groups as well. All you have to do is assign the name of the computer to the variable strDomain. Or, if you like things a little neater, change strDomain to a variable named strComputer, like so:

strComputer = "atl-fs-01"

Set colGroups = GetObject("WinNT://" & strComputer & "")
colGroups.Filter = Array("group")

For Each objGroup In colGroups
    Wscript.Echo objGroup.Name 
    For Each objUser in objGroup.Members
        Wscript.Echo objUser.Name
    Next
    Wscript.Echo
Next

That’s all there is to it.

Incidentally, the Scripting Guy who writes this column actually has one more Martin Luther anecdote: as a young monk Luther used to punish himself by lying outside in the snow … at night … in the middle of winter. So why doesn’t the Scripting Guy who writes this column like to relate that anecdote? That’s easy: it’s almost mid-year review time here at Microsoft, and he doesn’t want to give his manager any ideas.