Windows’s auditing policies allow storing log-on and log off events in the event logs. When enabled, every successful (and unsuccessful) log-on and log-off event can be found inside the Security event logs.
This article will show you how to get user logon/logoff history from Event Logs on the local and remote computer using PowerShell commands and a script.
Table of Contents
Prerequisite: Enable Login Auditing in Group Policy
Before retrieving user login history using PowerShell, you must enable login auditing in Group Policy on all domain-joined computers. Here’s how to do it:
- Log on to your domain controller.
- Press WIN + R to open the Run dialog.
- Type gpmc.msc and press Enter. This command opens the Group Policy Management Console.
- In the left pane, navigate to Forest: forest name > Domains > your domain.
- Right click on the Default Domain Policy and click Edit.
- In the left pane, navigate to Computer Configuration > Policies > Windows Settings > Security Settings > Advanced Audit Policy Configuration > Audit Policies > Logon/Logoff.
- Open the Audit Logoff and Audit Logon policies. Enable the select Success and Failure checkboxes, and then click OK.
- Close the Local Group Policy Editor and wait for the policy to replicate across the domain.
Now, when users logons locally or remotely to the domain-joined computers, each event will be logged as event IDs 4624 and 4634 for log on and log off events.
Get Windows User Login History using PowerShell
Let’s try to perform some get user login history PowerShell commands. For these examples, we’ll use the Get-WinEvent cmdlet—the main star of this show.
Note. All logon and logoff audit events are inside the Security event logs.
To get all log on and log off events from the Security log for all users
The below command gets all log on and log off history of all users who logged on to the computer.
Get-WinEvent -FilterHashtable @{ Logname = 'Security' ID = 4624,4634 }
To get log on and log off events from the Security log for all users within a specific timeframe
In this example, we’ll get the events between (StartTime) 2023-03-10 and (EndTime) 2023-03-12.
Get-WinEvent -FilterHashtable @{ Logname = 'Security' ID = 4624, 4634 StartTime = '2023-03-10' EndTime = '2023-03-12' }
Note. Check our tutorial on how to get list of installed programs in Windows.
To get all log on and log off events from the Security log for a specific username
In this example, let’s get the log on events for the user speed.racer.
On Windows PowerShell, add the Data filter to specify a username:
# On Windows PowerShell Get-WinEvent -FilterHashtable @{ Logname = 'Security' ID = 4624, 4634 StartTime = '2023-03-10' EndTime = '2023-03-12' Data = 'speed.racer' }
On PowerShell Core (7+), use the TargetUsername filter instead:
# On PowerShell Core (7+) Get-WinEvent -FilterHashtable @{ Logname = 'Security' ID = 4624, 4634 StartTime = '2023-03-10' EndTime = '2023-03-12' TargetUserName = 'speed.racer' }
PowerShell Script to Get User Login History
Using the Get-WinEvent cmdlet to get the user login history is an excellent way to do manual querying. If you run any of the example commands in the previous section, you’ll see a similar result to the one below.
Note. Check our tutorial on how to use GPO to manage, add, modify, import, and delete registry keys.
The output could be more easily readable. That’s where PowerShell scripting becomes useful. We can filter and format the output with a script to produce more understandable information.
Save the below script as Get-LogOnHistory.ps1. You can also download this script from this GitHub repository.
# Get-LogOnHistory.ps1 [CmdletBinding()] param ( [Parameter()] [String] $Username , [Parameter()] [datetime] $StartTime , [Parameter()] [datetime] $EndTime , [Parameter()] [switch] $IncludeLogOff , [Parameter()] [string] $ComputerName = $env:COMPUTERNAME ) # Base filter $filter = @{ LogName = 'Security' ID = @('4624') ProviderName = 'Microsoft-Windows-Security-Auditing' } # If IncludeLogOff is specified, add event 4634 to the filter if ($IncludeLogOff) { $filter['ID'] += '4634' } # If StartDate is specified if ($StartTime) { $filter.Add('StartTime', $StartTime) } # If EndDate is specified if ($EndTime) { $filter.Add('EndTime', $EndTime) } # Add username filter if ($Username) { ## If PowerShell Core if ($PSVersionTable.PSEdition -eq 'Core') { $filter.Add('TargetUserName', $Username) } ## If Windows PowerShell else { $filter.Add('Data', $Username) } } # <https://learn.microsoft.com/en-us/windows/security/threat-protection/auditing/basic-audit-logon-events#configure-this-audit-setting> $logOnTypeTable = @{ '2' = 'Interactive' '3' = 'Network' '4' = 'Batch' '5' = 'Service' '6' = 'Unlock' '7' = 'NetworkCleartext' '8' = 'NewCredentials' '9' = 'RemoteInteractive' '10' = 'RemoteInteractive' '11' = 'CachedInteractive' } try { $events = Get-WinEvent -FilterHashtable $filter -ErrorAction Stop -ComputerName $ComputerName foreach ($event in $events) { [PSCustomObject]@{ TimeStamp = $event.TimeCreated EventType = $( if ($event.Id -eq '4624') { 'LogOn' } else { 'LogOff' } ) User = $( if ($Username) { $Username } elseif ($event.Id -eq '4624') { $event.Properties[5].Value } else { $event.Properties[1].Value } ) SourceIP = $( if ($event.Id -eq '4624') { $event.Properties[18].Value } else { $null } ) ComputerName = $ComputerName LogOnType = $logOnTypeTable["$($event.Properties[8].value)"] } } } catch { $_.Exception.Message | Out-Default return $null }
Script Parameters
This script has five parameters that you can use to customize the results. Note that all parameters are optional.
- -Username — Here you can enter the specific username to check.
- -StartTime — Enter the start time to limit the oldest event to return.
- -EndTime — Enter the end time to limit the newest event to return.
- -IncludeLogOff — This is a swtich parameter. Use this if you want to include the logoff events. If not specified, only the log on events will be returned.
- -ComputerName — The target computer name to query. If you do not specify a computer name, the default will be the local computer.
Note. Learn how to get Windows version using PowerShell.
Get All Log On Events
Running the script without any parameters will return all log on events on the local computer:
.\Get-LogOnHistory.ps1
The LogOnType value shows the method of login used by the account.
Refer to Audit logon events to learn the definition of each LogOnType.
Get All Log On and Log Off Events
With the -IncludeLogOff switch, the script returns the log off events.
.\Get-LogOnHistory.ps1 -IncludeLogOff
For obvious reasons, the LogOnType value is empty for all log off events.
PowerShell Get Specific User Login History
When you only need to return the login history of a specific user, use the -Username parameter and provide the username (samaccountname).
.\Get-LogOnHistory.ps1 -Username speed.racer
PowerShell Get Specific User Login History on a Remote Computer
If you want to get the user’s login history on a remote computer, use the -ComputerName parameter and specify the remote computer name or FQDN.
In this example, the script retrieves the login history of the user superadmin on the theitbrosdc1 computer.
.\Get-LogOnHistory.ps1 -Username superadmin -ComputerName theitbrosdc1
Note. The Remote Event Log Management (RPC) inbound rule must be enabled on the target remote computer for this to work.
Otherwise, you will get an error similar to the one below.
Or if you specify a non-existent remote computer, you’ll get an error like this. The theitbrosdc2 computer does not exist in this environment.
Conclusion
That’s it! You now know how to get Windows 10 user login history using PowerShell. You can use this information to monitor user activity on your computer and detect any unauthorized access attempts.
3 comments
This is now in my powershell script library! THX
I did change
$userlog =”jsmith”
To
$username = Read-Host -Prompt “Enter UserName to search for”
$userlog = Read-Host -Prompt “Enter UserName to search for”
This Script can only be run by an admin user. Is it possible that a NON -admin User can run this script and save this information in excel?
Also how can we get this information for each month?
Can we schedule this script to run on a particular date and get he data for last month (30-31 Days)