How Can I Distinguish Between Local Users and Domain Users?


Hey, Scripting Guy! Question

Hey, Scripting Guy! When using a script to return members of the local Administrators account, how can I distinguish between local users and domain users?

— KS

SpacerHey, Scripting Guy! AnswerScript Center

Hey, KS. You know, many years ago there was a TV game show called What’s My Line? The premise of the show was that some person with an unusual occupation would come out on stage and a panel of celebrities would quiz this person, asking a bunch of Yes-No questions and trying to determine what his or her unusual occupation was. (Hey, all we said was that it was a game show; we never said it was an exciting and fun-filled game show.) If a panelist asked the right questions, then he or she might be able to determine the person’s occupation. If they asked the wrong questions, though ….

We have the same sort of situation here. (Hey, who said, “Beginning with the fact that this column is neither exciting nor fun-filled?” What could possibly be more exciting and fun-filled than distinguishing between local user accounts and domain user accounts?) Suppose we have a script that returns the members of the local Administrators group on a computer named atl-fs-01. That script might look something like this:

strComputer = “atl-fs-01”

Set colGroups = GetObject(“WinNT://” & strComputer & “/Administrators”)

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

When we run the script we’ll get back information similar to this:

Domain Admins
InfoSec Secure Environment

That’s great but, as you pointed out, KS, we have no way of knowing whether kenmyer (to pick one) is a local user or a domain user. As celebrity panelists (the Scripting Guys are about as famous as most of the “celebrities” who appeared on What’s My Line?), our job is to figure out what question we can ask that will tell us whether these are local users or domain users. That’s not an easy task, either, because we need to use the WinNT provider to get information about these users; as we all know, the WinNT provider (unlike its Active Directory counterpart) can tell us only a few things about a given account on a local computer.

Fortunately, though, one of the questions we can ask of the WinNT provider is this: “What is the ADsPath for the user?” (OK, so it’s not a Yes-No question. But we’re not really playing What’s My Line? here. That was just an analogy.) The ADsPath for a user account is roughly equivalent to a UNC path for a file. For example, suppose we have a file with the UNC path \\atl-fs-01\public\kenmyer\test.doc. The UNC path tells us exactly where the file Test.doc can be found: it’s on the computer atl-fs-01, on the shared folder Public, in the KenMyer folder.

Likewise, suppose we have an ADsPath like this: WinNT://FABRIKAM/atl-fs-01/Administrator. That tells us that we have a local account named Administrator which can be found on the computer atl-fs-01, which is a member of the Fabrikam domain. In other words, local accounts will always feature the name of the computer as part of the ADsPath; domain accounts will not. For example, here’s what we get back when we echo back the ADsPath for the members of the Administrators group:

WinNT://FABRIKAM/Domain Admins
WinNT://FABRIKAM/InfoSec Secure Environment

There you have it. If you look closely, you’ll see that the string /atl-fs-01/ appears in two of the paths: the one for Administrator and the one for PilarAckerman. Consequently, those two must be local accounts, and the other accounts must be domain accounts.

But, needless to say, we don’t want to look closely, do we? Instead, we want the script to just tell us which accounts are local users and which accounts are domain users. The following script should do just that:

strComputer = “atl-fs-01”
strTestString = “/” & strComputer & “/”

Set colGroups = GetObject(“WinNT://” & strComputer & “/Administrators”)

For Each objUser In colGroups.Members If InStr(objUser.AdsPath, strTestString) Then Wscript.Echo “Local user: ” & objUser.Name Else Wscript.Echo “Domain user: ” & objUser.Name End If Next

As you can see, this script starts out by assigning the name of the computer to a variable named strComputer. We then take the name of that computer (atl-fs-01) and add a / to the beginning and the end (/atl-fs-01/). This value is assigned to a variable named strTestString. Why do we need to add the / to the beginning and the end? To be honest, it’s more a safeguard than anything else. It’s unlikely you would, say, have a domain named atl-fs-01999, but putting /’s before and after the computer name helps ensures we don’t inadvertently identify a domain account as a local account.

After setting up our variables we then use this line of code to bind to the local Administrators account on the computer atl-fs-01:

Set colGroups = GetObject(“WinNT://” & strComputer & “/Administrators”)

What we want to do now is loop through the value of the Members property, a multi-valued attribute that lists each of the members of the Administrators group. For each user in the group we use this line of code to determine whether our test string (/atl-fs-01/) can be found anywhere within the user’s ADsPath:

If InStr(objUser.AdsPath, strTestString) Then

If the string is found, we assume that this is a local user and echo back that fact; if the string is not found then we assume that this is a domain user, and we echo back that fact. When all is said and done, we get back a nice little report that looks like this:

Local user: Administrator
Domain user: Domain Admins
Domain user: kenmyerp
Domain user: InfoSec Secure Environment
Local user: pilarackerman
Domain user: jonathanhaas

It’s not the fanciest output in the world, but it tells you what you need to know.

So there you have it: the scripting version of What’s My Line? Next time out we’ll do a scripting version of Fear Factor. With that in mind, you might want to brush up on your spider eating and your banana slug daiquiri drinking. And don’t forget to spend some time sitting in a bathtub filled with toads and alligators (although that’s something every scripter should be doing anyway).


Discussion is closed.

Feedback usabilla icon