The PowerShell Get-LocalUser
cmdlet gives you information about a local user, including the last logon time.
PS> Get-LocalUser Fred | Format-List AccountExpires : Description : Enabled : True FullName : PasswordChangeableDate : 04/02/2023 2:25:04 PM PasswordExpires : UserMayChangePassword : True PasswordRequired : False PasswordLastSet : 04/01/2023 2:25:04 PM LastLogon : 04/01/2023 2:28:41 PM Name : Fred SID : S-1-5-21-162119347-98882960-612995125-1001 PrincipalSource : Local ObjectClass : User
How can you get this information from C++?
For historical reasons, commands for operating with local users are in the LAN Manager API family. That’s because MS-DOS was a single-user operating system, so the only time you had to worry about “users” was if you were operating over the network.
This is also why a bunch of user management operations are handled by NET.EXE
. The NET.EXE
program was the part of LAN Manager that gave you access to all the network magic stuff.
C:\> NET USER Fred User name Fred Full Name Comment User's comment Country/region code 000 (System Default) Account active Yes Account expires Never Password last set 04/01/2023 2:25:04 PM Password expires Never Password changeable 04/02/2023 2:25:04 PM Password required No User may change password Yes Workstations allowed All Logon script User profile Home directory Last logon 04/01/2023 2:28:41 PM Logon hours allowed All Local Group Memberships *Administrators Global Group memberships *None The command completed successfully.
The native function for getting this information is NetUserGetInfo
. In particular, asking for information level 2 gives you a USER_INFO_2
structure which contains, among other things, usri2_last_logon
.
The documentation includes a sample program showing how to request various levels of information and then print the results, so I won’t bother repeating it here.
If you are ever short of ideas for blog posts, here's a list of very obscure questions on this topic and adjacent ones:
(1) What is the relationship between net.exe and net1.exe–why do they both exist? is it true that some commands are implemented by the second but not the first? if so, why? (2) I believe that "Country/region code" was only ever used by downlevel clients (such as DOS, OS/2, Win3.x, maybe 9x/Me) – can you confirm that? (3) Did anything ever use the code page setting (usri2_code_page)? It seems odd that net.exe doesn't display it or let you change...