Hey, Scripting Guy! How Can I Get the Name of the Last User to Log on to a Computer?

Hey, Scripting Guy! How Can I Get the Name of the Last User to Log on to a Computer?

  • Comments 6
  • Likes

Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I get the name of the last user to log on to a computer?

-- SV

SpacerHey, Scripting Guy! AnswerScript Center

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:

Wscript.Echo strValue

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.

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Dear Scripting Guy,

    The DefaultUserName and DefaultDomainName values don't get populated in Windows 7. They're under Wow6432Node, but their values are blank.

    Any thoughts on an alternative with support for 2000 - 2008R2/7 ?

    Thanks

  • If you use powershell:

    (get-wmiobject win32_computersystem).UserName

    ... will give you the currently logged on user.

  • Emil Rakoczy....I've been trying to find this forever.  THANK YOU!

    (get-wmiobject win32_computersystem).UserName

  • Note that this: '(get-wmiobject win32_computersystem).UserName' only works for logons at teh console.  It will not tell you about someone logged on remotely via RDP.

  • You can also sort the user profiles by modifed date and get the last logged on user that way.

  • Pre Windows 7, I used to use the DefaultUserName to determine who was logged on.  If explorer.exe was running, then the DefaultUserName would tell you who was currently logged on.  Then I tried this on Windows 7 and only sometimes is this value populated.  It also did not tell you if there was more than one user logged on.  Instead, I use the owner of the Explorer.exe process.  There is always at least one explorer.exe process for every usesr that logs on.  Here is the code I use:

    Function WhosLoggedOnTS(strComputer)

    on error resume next

    dim strUsers

    dim objWMIService

    dim colProcessList

    dim objProcess

    dim strNameOfUser

    dim strUserDomain

    dim colProperties

    strUsers=""

    Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

    Set colProcessList = objWMIService.ExecQuery("Select * from Win32_Process")

    For Each objProcess in colProcessList

       colProperties = objProcess.GetOwner(strNameOfUser,strUserDomain)

       If objProcess.Name = "explorer.exe" then

           strUsers = strUsers & strNameOfUser & "," & GetFullName(strNameOfUser)

       End If

    Next

    If strUsers="" then

    strUsers="Logged Off"

    End If

    Set objWMIService=Nothing

    Set colProcessList=Nothing

    Set objProcess=Nothing

    WhosLoggedOnTS=strUsers

    End Function

    Now I've been asked to find a way to determine who was last logged on......