Hey, Scripting Guy! How can I get the name of the last user to log on to a computer?
Hey, SV. You know, the Scripting Guy who writes this column never watches the news on TV. (OK, sports news being the one exception.) That’s not because he doesn’t like to keep up with current events, it’s just because – well, let’s give you an example. The other night the Scripting Guy who writes this column was at the gym, dutifully riding the exercise bike. The news happened to be on, and he glanced up from his exertions and caught a story about the “wacky weather” (their phrase, not his) that recently roared through Europe. After showing a number of suitably wacky scenes (mostly of people and things being blown around by the wind) the segment concluded with the newscaster noting, “41 people died in the recent windstorms.”
Forty-one people died in those “wacky windstorms?” That’s why the Scripting Guy who writes this column doesn’t watch the news on TV. That’s also why he writes Hey, Scripting Guy!, the daily scripting column where you get all of the wackiness without any of the fatalities.
Or at least without as many fatalities.
For example, here’s a script that reports back the name of the last user to log on to a computer, and does so without causing anyone any pain or suffering.
Or at least not any permanent pain or suffering:
Const HKEY_LOCAL_MACHINE = &H80000002 strComputer = "." Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv") strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon" strValueName = "DefaultUserName" objRegistry.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue Wscript.Echo strValue
As it turns out, any time a user logs on to a computer his or her logon name is saved in the registry; in particular, that name is stored in HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\WinLogon\DefaultUserName. (As an added bonus, the user’s domain is stored in the same registry key, in the value DefaultDomainName.) If we want to know the name of the last user to log on to a computer all we have to do is read the value of DefaultUserName.
Now, admittedly, this is not 100% guaranteed; that’s because it’s possible to change the value of (or even erase) DefaultUserName. In theory, someone with the user name kenmyer could log on to a computer and then change the value of default user to, say, pilarackerman. We’re willing to bet, however, that scenarios such as that don’t happen all that often; consequently, while this approach isn’t guaranteed it’s still going to work more often than not.
Which is something you can’t say about the Scripting Guy who writes this column.
Note. Does that mean that you use this same script to determine which user is currently logged-on to a computer? Well, maybe, assuming that someone is logged on to the computer; after all, the value of DefaultUserName remains in the registry even if no one is logged-on to the machine. If you’re interested in determining which user is currently logged-on to a computer you might check to see if Explorer.exe is running and, if it is, determine the owner of that process. But that’s another column for another day.
As you can see, our script begins by defining a constant named HKEY_LOCAL_MACHINE, with a value of &H80000002; this constant tells WMI’s Standard Registry provider which registry hive we want to work with. After defining the constant we then connect to the WMI service on the local computer, taking care to bind the root\default namespace (not the much-more commonly-used root\cimv2 namespace). And yes, we could easily connect to the WMI service on a remote computer; all we have to do is assign the name of that remote machine to the variable strComputer:
strComputer = "atl-fs-01"
After hooking up with the WMI service we then assign values to a pair of variables: the variable strKeyPath is assigned the registry path within HKEY_LOCAL_MACHINE, and the variable strValueName is assigned the name of the registry value we want to read (DefaultUserName). We then use the GetStringValue method to read the registry and store the name of the last user to log on to the computer in an out parameter named strValue:
objRegistry.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue
Note. What’s an “out parameter?” An out parameter is simply a variable that we hand to a method; notice that strValue is the final parameter supplied to the GetStringValue method. In turn, the method assigns a value to that variable for us. In this case, of course, that value happens to be the value of DefaultUserName.
All we have to do now is echo back the value of the variable strValue and we’re done:
Incidentally, if you’re interested in getting back the domain name as well as the logon name, well, here’s a script that does just that:
Const HKEY_LOCAL_MACHINE = &H80000002 strComputer = "." Set objRegistry=GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv") strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon" strValueName = "DefaultUserName" objRegistry.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue Wscript.Echo strValue strValueName = "DefaultDomainName" objRegistry.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue Wscript.Echo strValue
And by the way, this really is true: Hey, Scripting Guy! has been running for over two and a half years now, and, to the best of our knowledge, no one has ever died from reading the column. (See? We told you that you couldn’t really be bored to death.) Admittedly, doctors point to the fact that Scripting Guy Peter Costantini has been in a coma for years as cause for concern. However, even that issue is controversial: Peter insists that he’s not in a coma, but the doctors refuse to change their diagnosis. The rest of the Scripting Guys have no comment on the issue, although we’re not sure whether, in Peter’s case, it really makes all that much difference anyway.