Back in May John asked:
“Hi There
Is there a tool that can run and provide a list of “last logon” with date and time, I need something to show like a activity list. It would help re-deploying PC’s from one location to another based on use.”
I am glad you asked about this John. I never knew this information was saved in Windows. You can easily access it using VB Script.
There is a WMI object called Win32_NetworkLoginProfile. It allows us to see all the users that have logged on to a machine, and information about them.
Lets start out with a simple script that just spits out all the users that have logged into a machine:
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_NetworkLoginProfile")
For Each objItem in colItems
Wscript.Echo objItem.Name
Next
Here is what the output looks like:
You might notice something with our list. It always includes accounts like “NT AUTHORITY\SYSTEM” or “NT AUTHORITY\LOCAL SERVICE”
We don’t want those – we just want to see what users have logged in.
If you browse on over to the Microsoft website, we can see all the options provided in the Win32_NetworkLogonProfile object
Looking there we can see that the “UserType” variable is set to the string “Normal Account” for all standard logon accounts.
Using this info, we can change our script to not show those accounts:
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_NetworkLoginProfile")
For Each objItem in colItems
if (objItem.UserType = "Normal Account") then
Wscript.Echo objItem.Name
end if
Next
See our list now:
How do we know who was the last to logon? The LastLogon field will let us know. The bigger this number is, the later the logon.
Knowing this, we can change our script to look like this to only show us the last logon:
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_NetworkLoginProfile")
iLastLogon = 0
sLastUser = "Unknown"
For Each objItem in colItems
if (objItem.UserType = "Normal Account") then
if (iLastLogon
We can pull out the date and time by parsing out this info. I won't keep bombarding you with code, so if you want to see how I did it, just look at the scripts I link below.
Here is what the output looks like from my final script:
We had so much fun playing with this info we did a few things. We have two scripts (Linked at the bottom of the article) that will:
-Show you a complete list of who logged in with dates and times
-Show you who logged in last
In addition, we added both of these reports to Network Administrator.
First the Last Logon Report:
Second, a complete list of who logged on to a computer:
The nice thing about that last one it even tells you the number of times an account was used to logon.
One thing to keep in mind when using Network Administrator, or another tool to push these scripts on to remote machines - Don't use the same account you are trying to audit.
For example, if you wanted to see if anyone had used the administrator account to access a PC...then don't use the administrator account to check it! Otherwise the last logon will be you (Network Administrator automatically looks at every account other than the one you are using).
Get a copy of Network Administrator from our download Page
Here are the downloads for the two scripts:
This is the one that shows you the complete report:
This is the one that shows you the last logon
Rename them to .vbs after downloading.
One more thing...Subscribe to my newsletter and get 11 free network administrator tools, plus a 30 page user guide so you can get the most out of them. Click Here to get your free tools
{ 20 comments… read them below or add one }
Nice scripts steve. I noticed on my computer the guest account is always getting hit when I log in. Any reason for this?
Hi Derick,
I noticed this too. I think it may be windows itself doing something with the guest account.
Cool addition to network administrator. Thanks for the update.
Users interested in this may also find uptime.exe useful.
http://support.microsoft.com/kb/232243
Thanks for link Don. Did not know about that utility.
Hi Steve,
Thank you for that info, I had been using which to retrieve the login info, didn’t know about this one.
Another good one I use is system info, you can use that to get either the uptime or boot time of a machine, depending on the so version uptime isnt available.
Hi guys,
I had learned many things from this site.I am System Administrator in one company and we are using Windows 2008 R2 server and XP for client pc’s.I want to monitor who had access the shared folder in server, is there any tool available to check who had access the server and who had copy the files and deleted the files in server.
So kindly help us to solve above issues.
Regards,
M.Bala
Hello Bala,
You need to use auditing…and it has to be turned on before anything happens…since it won’t tell you after the fact.
Here is an article that walks you through it:
http://www.intelliadmin.com/index.php/2008/03/use-auditing-to-track-who-deleted-your-files/
I ran both of the new additions from Network Administrator and received some strange results when I ran it against the entire domain. For example, the results showed that the company controller had logged into a lot of systems, and several other regular users logged into 3, 4, or 5 systems other than the ones they normally sit at. I am positive that this didn’t happen. In fact, we have the users lock their computers before leaving for the day. To test this, I initated an RDP session to several machines and they were still locked, under the corrrect users accounts. What I think is happening seems to be common for a lot of Windows Scripting. What I have experienced in the past is, when a script fails to return any meaningful (i.e. limited or missing)information for a system, it substitutes the values it received from the last successfully tested device. I wish this worked better but I have seen this on many networks over the years.
Hi Steve,
I actually think it is possible that they still logged into those systems. This info is pulled right from windows…but it is not only updated when you login to the desktop,
For example, are any of those machines being used for sharing printers or sharing files? If so, when connecting to these shares they would be considered a “logon”
One thing that would be interesting to know is if you run those scripts I put in the article manually on the machines do they still show the same info?
Then again, it could be possible that windows is returning bogus info.
Thanks,
Steve
Hi Steve,
1. You can get the same info from the built in Event viewer\security but yes auditing needs to be turned on and your tool is a little cleaner
2. If an account was locked and then unlocked the script will consider that as a logon which is not accurate especially if I want to know the logon time, any solutions to that?
Thank you,
David
Hi David,
No a lock/unlock is not counted. What is more annoying is if a user connects to your computer via file sharing it *will* register as a logon. Still have not found a way around this.
Also, some people have reported to me that if a machine goes to sleep, and is woken up…that will count
So we are still playing around with this to see if we can get more accurate info out of windows.
What would be perfect is if we could just pull out the last user to actually login to a desktop and nothing else. That type of info could be really valuable.
Okay, the client’s domain has 4 offices, Dallas, Houston, Amarillo and Mexico City. in Mexico City, the fired 3 people, and instead of disabling the user accoutnts, I was told to log into their systems, change their passwords, then lock the machines. This way, we could capture exactly what they were doing, and no one else could log into their machines, even the local manager (w/o rebooting).
Then, I received and installed your update, and ran both variations of the “Last Logged On” additions the very next day. It caught my attention that those specific systems showed up as being logged into by an unrelated user from the same office, not the user that I had locked the machine with (same user on all 3 systems).
Obviously, I was a little upset thinking that the person shown had rebooted the system and logged in when, by locking the PCs, no one should have been able access them.
So, I immediately initiated an RDP session, providing the administrator’s username and password but was presented with a warning on each system that the PC was logged in under the same user name that I had originally locked them uner. I saw this occur in groups across the domain. As I said in my previous post, I have seen similar utilities return the same sort of results.
My comments were just a warning that this happens sometimes so you have to do a “reality check”.
I hear you Steve….thanks for the detailed description. Thanks for taking time to comment.
I think what you do is awesome, I appreciate everything you turn out, and wanted to point out … I was in no way trying to “steal your thunder”.
I DO get upset sometimes with the inconsistencies we find in such things. I truly believe Microsoft does some wonderful things, but then, when you need them to do something simple like returning accurate results on important items such as this, they just “let it go”. These bugs will stay with them forever and they won’t fix them, which is why a lot of these “goodies” go unnoticed. You know, the 5 minutes of time/work needed by a single programmer to make these tools work could improve millions of lives, if only in a small way, and it would certainly help to reduce the frustrations they cause by leaving “broken” toys lying around for people to trip over.
Enough of that. I programmed in a dissimilar programming environment (Pick Operating System and its variants) for over 20 years. Even though I no longer do programming, per se, I still have a ton of insight into how things should, could or would work, and how they may or may not be used.
I take care of a couple hundred systems on a regular basis, so I have the access needed to test things out for you. I would be happy to report back “the good” and “the bad” that I run into.
Just a thought …
Steve
I did not feel that way at all Steve, in fact I really appreciate that you took the time to comment. Your thoughts made me look further into this, and this method really has its issues.
One way I think I have found that is quite reliable is the event log. I will have a posting soon on this…the only downside is that under XP security auditing is not enabled by default (This is needed for logons to be put in the event log)
Hello Everyone,
I have put up a new script that uses system auditing instead of this WMI object.
Here is the post:
http://www.intelliadmin.com/index.php/2012/07/see-who-logged-on-to-a-computer-and-when/
I wrote these two scripts to write events to the Application Log on the local machine when a user logs on and off to support security requires where I last worked.
‘Script to write Logon Data Username, Computername, and IP address to eventlog.
Dim objShell, WshNetwork, PCName, UserName, strMessage
Dim strQuery, objWMIService, colItems, strIP
‘ Constants for type of event log entry
const EVENTLOG_INFORMATION = 4
set objShell = CreateObject(“WScript.Shell”)
Set WshNetwork = WScript.CreateObject(“WScript.Network”)
Set objWMIService = GetObject( “winmgmts:” & “{impersonationLevel=impersonate}!\\” & “.\root\CIMV2”)
PCName = WshNetwork.ComputerName
UserName = WshNetwork.UserName
strQuery = “SELECT * FROM Win32_NetworkAdapterConfiguration WHERE MACAddress > ””
Set colItems = objWMIService.ExecQuery( strQuery, “WQL”, 48 )
For Each objItem In colItems
If IsArray( objItem.IPAddress ) Then
If UBound( objItem.IPAddress ) = 0 Then
strIP = objItem.IPAddress(0)
Else
strIP = Join( objItem.IPAddress, “, ” )
End If
End If
Next
strMessage = “Logon Event Data” & VBCrLf & “PC Name: ” & PCName & VBCrLf & “Username: ” & UserName & VBCrLf & “IP Addresses: ” & strIP
objShell.LogEvent EVENTLOG_INFORMATION, strMessage
*****************************************************************************
‘Script to write Logoff Data Username, Computername to eventlog.
Dim objShell, WshNetwork, PCName, UserName, strMessage
Dim strQuery, objWMIService, colItems, strIP
‘ Constants for type of event log entry
const EVENTLOG_AUDIT_SUCCESS = 8
set objShell = CreateObject(“WScript.Shell”)
Set WshNetwork = WScript.CreateObject(“WScript.Network”)
PCName = WshNetwork.ComputerName
UserName = WshNetwork.UserName
strMessage = “Logoff Event Data” & VBCrLf & “PC Name: ” & PCName & VBCrLf & “Username: ” & UserName
objShell.LogEvent EVENTLOG_AUDIT_SUCCESS, strMessage
Excellent stuff Jeff. Thank you for taking the time to post this for everyone.
If you are going to copy and paste the above code…make sure you replace the quotes…since wordpress uses Unicode ” instead of standard ASCII quotes.
Awesome stuff from you guys, I was wondering if it’s possible to have your script write output to a csv file instead so I can filter through. Thank you