How Can I Determine if the Local Administrator Account has been Renamed on a Computer?

ScriptingGuy1

Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I determine if the local administrator account has been renamed on a computer?

— KF

SpacerHey, Scripting Guy! AnswerScript Center

Hey, KF. You know, our first thought was to tell you to use ADSI and try to bind to the local administrator account on the computer; if that failed, that would mean that there was no account named Administrator on that computer. In turn, that would mean that the account had either been renamed or deleted.

But then we thought about this a little more. (Yes, having two thoughts in a single day is a Scripting Guys record.) Suppose the local administrator account had been renamed. In that case, you’d probably want to know the new name for the account. So what we really want to know is the name of the local administrator account. Period.

But how can we know the name of the account if the account has been renamed? (This is the scripting equivalent of, “If a tree falls in the forest and no one is there to hear it, does it still make a sound?”) Why, through the magic of the “well-known SID,” of course. A SID, as you probably know, is a “security identifier,” a unique identifier assigned to each account on a computer. The computer actually uses the SID to keep track of each account: if you rename the administrator account the computer still knows which account is the administrator account. That’s because the SID – unlike the name – never changes.

Now that sounds pretty good except for one thing: if the SID is a unique identifier then how can we determine which SID represents the administrator account? That’s where the “well-known” part comes in. On a computer the SID for a local administrator will always begin with S-1-5- and end with -500. (That’s why the administrator SID-and other SIDS, such as SIDs for the Guest account-are considered well-known.) For example, you might have a SID that looks like this:

S-1-5-21-1559272821-92556266-1055285598-500

As you can see, our SID starts with S-1-5- and ends with -500. If we can find a SID that fits that pattern, then we’ve found our local administrator account.

So can we find a SID that fits that pattern? Yes, by using a script like this:

strComputer = “.”

Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2”)

Set colAccounts = objWMIService.ExecQuery _ (“Select * From Win32_UserAccount Where LocalAccount = TRUE”)

For Each objAccount in colAccounts If Left (objAccount.SID, 6) = “S-1-5-” and Right(objAccount.SID, 4) = “-500” Then Wscript.Echo objAccount.Name End If Next

Note. This particular script works only on Windows XP and Windows Server 2003. In a minute we’ll show you a way to perform this same task on Windows 2000 Server or Windows NT Server 4.0.

We begin by connecting to the WMI service on a computer, then use this query to retrieve a list of local computer accounts:

Set colAccounts = objWMIService.ExecQuery _
    (“Select * From Win32_UserAccount Where LocalAccount = TRUE”)

Note the use of the Where clause Where LocalAccount = TRUE. That ensures that we get back only local accounts; we aren’t interested in weeding through domain accounts. This is also the reason why this particular script won’t run on Windows 2000 or Windows NT 4.0; the LocalAccount property wasn’t introduced until Windows XP.

After getting back a collection of local user accounts we set up a For Each loop and walk through the collection. For each account we use this line of code to see if the account fits the well-known SID pattern:

If Left (objAccount.SID, 6) = “S-1-5-” and Right(objAccount.SID, 4) = “-500” Then

As you can see, we simply check to see if the first six characters in the string equal S-1-5- and if the last four characters equal -500. If they do then we’ve found the local administrator account and we echo the account name. If they don’t, then we loop around and check the next account in the collection.

That should do the trick, provided that you’re running the script on Windows XP or Windows Server 2003. If you’re running on Windows 2000 Server or Windows NT Server 4.0 you can use this variation. (This version will also work on Windows XP and Windows Server 2003.) In this script we begin by assigning the name of the computer to the variable strComputer; note, too that we need to use the actual computer name and not the dot (a WMI shortcut method for indicating the local machine). We have to use the computer name because we’ll use this variable to look for accounts with a “domain” that matches the computer name. (It’s confusing, but in a technical sense a computer is a domain, though obviously not on the scale of something like Active Directory.) Although a dot might represent the local computer name in WMI, it does not represent a domain name. Therefore, we must be very explicit when specifying the computer name.

And, yes, when dealing with a local computer account the domain name is equivalent to the computer name. If you have a user named kmyer and a computer named atl-ws-01, the domain name is atl-ws-01 and the user name is kmyer.

We then use a modified query to return a collection of accounts where the Domain is equal to the name of the local machine; that will eliminate Active Directory accounts and return only local accounts.

Here’s the script:

strComputer = “atl-ws-01”

Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2”)

Set colAccounts = objWMIService.ExecQuery _ (“Select * From Win32_UserAccount Where Domain = ‘” & strComputer & “‘”)

For Each objAccount in colAccounts If Left (objAccount.SID, 6) = “S-1-5-” and Right(objAccount.SID, 4) = “-500” Then Wscript.Echo objAccount.Name End If Next

Why are we so concerned with limiting the returned collection to local accounts? Well, without that clause the Win32_UserAccount class will try to return a list of all the user accounts in Active Directory as well as all the local user accounts. If you have an hour or two (or three) to kill, well, what the heck: go ahead and return – and weed through – several thousand user accounts if you want to. Otherwise you’re better off limiting the returned data to local accounts only.

0 comments

Discussion is closed.

Feedback usabilla icon