- Use PowerShell splatting and PSBoundParameters to pass parameters - Wed, Nov 9 2022
- Using PowerShell with $PSStyle - Mon, Jan 24 2022
- Clean up user profiles with PowerShell - Mon, Jun 9 2014
A question I hear often is how to track what computer a user has logged on to. Usually the implication is that the Windows administrator wants a central source that she can easily check. Well what is more central than Active Directory? Since the user can already write to a number of properties on their own user object, why not capture logon (and logoff data as long as we’re at it) and store it with the user?
The script
I wrote a short script that uses ADSI to accomplish this task. I chose this route to avoid requiring that the user’s desktop have any other modules or requirements. Here is my Set-UserStatus.ps1 script.
<# Set-UserStatus.ps1 **************************************************************** * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED * * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK. IF * * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, * * DO NOT USE IT OUTSIDE OF A SECURE, TEST ENVIRONMENT. * **************************************************************** #> Param( [Parameter(Position=0)] [ValidateSet("Logon","Logoff","Unknown")] [string]$Status="Unknown" ) #no spaces in the filter [adsisearcher]$searcher="samaccountname=$env:username" #find the current user $find = $searcher.FindOne() #get the user object [adsi]$user = $find.Path #define a string to indicate status $note = "{0} {1} to {2}" -f (Get-Date),$status.ToUpper(),$env:computername #update the Info user property $user.Info=$note #commit the change $user.SetInfo()
The script needs a single parameter to indicate Logon or Logoff. The default is Unknown. Because this will be running as Group Policy script, I didn’t want to worry about errors or prompts if the administrator set it up wrong. They would find that out as soon as they tested it, checked the user account and saw “Unknown” for the status.
The script uses ADSI to find the user’s account in Active Directory. It then writes a string with the date and time, the status (ie Logon or Logoff) and the computername. The string is written to the Info property, which is what you see as the Notes property on the Telephones tab.
Telephones tab
In my test domain, user accounts have permission to write to this property. You might want to pick a different property, perhaps one that doesn’t even show in the GUI. You’ll need to take steps to ensure users have permissions to write to that property on their own object.
Setting it up
To use, I followed the steps in my previous article to copy the script to a GPO and then added it. Because my script takes a parameter, I need to add it as I shown below.
Add PowerShell script to Logon scripts
If your script uses parameters, I think the best approach is to make them all positional in your script. The screenshots above depicts configuring the script for user logon. After finishing, I then double-clicked Logoff in the same GPO. I clicked Add and then Browse.
Now, I could have copied the script again to the Logoff GPO container, but since the script is the same, in the Explorer window I can click on Scripts in the path to navigate “up”
Scripts folder
Then double-click the Logon folder.
Navigate to Logon scripts
I can now pick the same script I used for logon.
Add to Logoff scripts
Of course, I need to make sure I set the parameter to Logoff.
Set the parameter to Logoff
When finished, I can configure any security filtering, link to the necessary organizational units, or the domain and I’m ready to go.
Results
When the user logs on or off, their user account will be updated as I showed in the first screenshot. Depending on your configuration and network, the status update might take a minute or two to show up in Active Directory. My script won’t give you an exact, to the second, time they logged on or off but a pretty close approximation. You might also need to take into account the effect this script might have on replication, so please test thoroughly in a non-production environment.
Of course, with PowerShell this is also easy to discover, and if you use a property that isn’t exposed in Active Directory Users and Computers, you will have no choice but to use PowerShell to find the status information.
Get user status with PowerShell
Or I can track a number of users.
PS C:\> Get-ADUser –filter "department –eq 'Customer Service'" –properties Info | Select Name,Info | Out-Gridview –title "CS Users"
Track multiple users
Summary
So there you go, a practical example of a PowerShell script for users. Now, in this particular case I suppose I could have written something similar using VBScript but this was much easier to do in PowerShell and if that is your management and scripting engine, why wouldn’t you use it!
Interesting way of doing it, I’ll have to think about this one some more…if you use a field that is there in ADUC you could possibly present the data in a column to access it without even opening the user’s properties. This is my way of tracking the data:
http://community.spiceworks.com/scripts/show/70-track-login-and-logout
It’s been working well for several years, and I use it at least once an hour!
great script!
is it possible to put seperators between the time | date | logon | computer name
and export it to csv?
Sure. Look at help for Export-CSV and you’ll see that you can specify a delimiter.
The script is not working in my ad.. May I get help please
It is very difficult to troubleshoot via comments but maybe we can get you at least headed in the right path. Of course, you are going to have to provide some information about what isn’t working.
i am looking for powershell script to get the user login information from the Windows 2012 for the last 10 Days.
Kindly help if any one have this.
Hi Jeff, nice post, still applicable today 🙂
Is the string overwritten every time at login or a new line is inserted into the attribute?
Following up on this, for whoever is interested in writing to a multi-value attribute.
You need to add PutEx; so based on Jeff’s example:
I had the same question, does it over write each time?
Yes Adam, it will overwrite. See the examples I’ve put in the comments for extended use.
Extra follow-up on this.
Based on the code from Jeff, we expanded the code to support:
a multivalued attribute (using otherMobile, just replace with what you need)
limit appending to 50 values (configurable) so as not to clog an attribute
This was very useful. I changed the login script line 24 to ‘$note = $env:computername’ and the logout script line to ‘$note = “NA”‘
Those allowed me to run a scheduled powershell script to both disable accounts and log off any of those accounts that were currently in use;
This is very useful in a school environment where we have timed assessments and Windows login hours does not match up with our lesson times.
Thank you!
Shaun