All user logon and logoff events can be configured in Windows audit policies to be logged in the Event Viewer security logs. You can use these events to track user activity on the machine. In this article, we will look at how to configure and get user logon history on Windows by using PowerShell.
Enable Windows Logon Auditing via GPO
Keep in mind that logon auditing may not be enabled with the required level of detail by default. You can enable it through Group Policy to audit every time a user logs on or off a device. In this example, we are going to enable the Logon Audit policy for all of the computers that are joined to the Active Directory domain (on a standalone computer, this policy can be enabled through the local GPO editor, gpedit.msc).
Note. Although you can config audit settings in the Default Domain Policy, we generally recommend you to create a dedicated Group Policy Object (GPO) for auditing and security monitoring settings. Using separate GPOs makes administration, troubleshooting, and change management easier, especially in large enterprise environments.
- Open the Group Policy Management Console (gpmc.msc)
- Create a new GPO (for example, Audit – Logon Tracking) and link it to the OU that contains the target machines. In smaller environments, you can also config these settings through an existing security baseline GPO.
- Navigate to Computer Configuration > Policies > Windows Settings > Security Settings > Advanced Audit Policy Configuration > Audit Policies > Logon/Logoff.
- Enable the Audit Logon and Audit Logoff policies. Select Success to track successful sign-ins and Failure if you also want to audit failed logon attempts (Event ID 4625).
Note. Logon auditing can generate a large number of security events, especially on DCs and file servers. Make sure the Security event log size and retention settings are configured appropriately.
- Close the GPO editor and update the policy setting on a client computer by running: gpupdate /force
Note. For more complete user activity auditing in enterprise environments, you should consider enabling additional audit policies related to authentication and privileged access. The basic Audit Logon policy generates Event ID 4624/4625 events, but other audit categories provide additional context during security investigations.
Here are the recommended audit settings:
Audit Policy Event IDs Purpose Audit Logon 4624, 4625 Tracks successful and failed logon attempts. Audit Logoff 4634, 4647 Tracks user logoff events and session termination. Audit Special Logon 4672 Tracks logons where special privileges are assigned (for example, administrative accounts). Audit Other Logon/Logoff Events 4648 Tracks logons that use explicit credentials. Audit Credential Validation 4776 Tracks NTLM authentication and credential validation attempts. Audit Kerberos Authentication Service 4768 Tracks Kerberos Ticket Granting Ticket (TGT) requests. Audit Kerberos Service Ticket Operations 4769 Tracks Kerberos service ticket requests for accessing network services.
The following example returns only RemoteInteractive (RDP) logon events:
Get-WinEvent -FilterHashtable @{
LogName='Security'
Id=4624
} |
Where-Object {
$_.Properties[8].Value -eq 10
} Now when users log on locally or remotely to a computer the following event appears in the Security log of the Event Viewer:
Event ID 4624: An account was successfully logged on.
Or:
Event ID 4634: An account was logged off.
The event details contain information about the username, domain, time, logon type, source IP, etc.
Important. Event ID 4624 alone does not always provide enough info to determine whether a privileged user actually performed an admin action. In enterprise environments, you should correlate Event ID 4624 with Event ID 4672 (Special Logon) to identify privileged sessions.
For detailed descriptions of Windows security audit events, including logon, logoff, account lockout, and authentication events, see Microsoft’s Windows Security Auditing documentation.
Important for DCs. On Active Directory DCs, Event ID 4624 does not always represent an interactive user sign-in. Logon Types 3 (Network) and 5 (Service) are especially common on DCs and usually do not indicate an interactive user session. The event may also be generated by Kerberos authentication, NTLM authentication, LDAP binds, computer account authentication, service logons, and other security operations. When analyzing logon activity on a DC, you should pay close attention to the Logon Type field and account name before treating an event as a user sign-in.

Common Windows Logon Types
| Type | Meaning |
|---|---|
| 2 | Interactive (console login) |
| 3 | Network |
| 4 | Batch |
| 5 | Service |
| 7 | Unlock |
| 8 | NetworkCleartext |
| 9 | NewCredentials |
| 10 | RemoteInteractive (RDP/Terminal Services) |
| 11 | CachedInteractive |
Logon Type 10 is typically generated by Remote Desktop (RDP) sessions and is often the most useful event when tracking remote admin access.
How to Check User Login History Using PowerShell
Then use the Get-WinEvent PowerShell cmdlet to get user logon and logoff events from event logs. For example, to get all logon and logoff events for a specific user account for a specific time period, run the command:
Get-WinEvent -FilterHashtable @{
LogName = 'Security'
ID = 4624,4634
StartTime = [datetime]'2024-11-10'
EndTime = [datetime]'2024-11-23'
} -MaxEvents 500 Note that -MaxEvents limits the amount of returned events. It does not reduce the number of events that Windows reads from the log. You should use filtering options in order to improve query performance.
For complex filtering cases/large Security logs, you can also use XPath queries:
Get-WinEvent `
-LogName Security `
-FilterXPath "
*[System[(EventID=4624)]]
and
*[EventData[Data[@Name='LogonType']='10']]
"

Check Failed Logon Attempts
Successful logons are recorded with Event ID 4624. In case you are troubleshooting authentication issues/investigating possible password attacks, you may also want to review failed logon attempts.
In order to display failed logon events, run the following command:
Get-WinEvent -FilterHashtable @{
LogName = 'Security'
ID = 4625
} Event ID 4625 is generated when Windows rejects a logon attempt. Note that the event details typically include the account name, logon type, source workstation, source IP address (for remote logons), and the failure reason.
Tip. If you are facing a large number of Event ID 4625 entries, this may indicate password guessing attacks, outdated service account credentials, scheduled tasks using expired passwords, or user account lockout issues.
For detailed info on Event ID 4625 fields, status codes, and failure reasons, see Microsoft’s Event ID 4625 documentation.
Get User Login History with PowerShell Script
The simple Get-WinEvent output is not convenient for tracking user logon/logoff activity. We have prepared a PowerShell script to extract user logon history from the Event Viewer log in a more convenient way.
Copy the script below and save it as Get-LogOnHistory.ps1. You can also download this script from this GitHub repository.
# Get-LogOnHistory.ps1
[CmdletBinding()]
param (
[Parameter()]
[String]
$Username
,
[Parameter()]
[switch]
$ExcludeSystemAccounts
,
[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'
'7' = 'Unlock'
'8' = 'NetworkCleartext'
'9' = 'NewCredentials'
'10' = 'RemoteInteractive'
'11' = 'CachedInteractive'
}
try {
$events = Get-WinEvent -FilterHashtable $filter -ErrorAction Stop -ComputerName $ComputerName
foreach ($event in $events) {
$userName = if ($event.Id -eq '4624') {
$event.Properties[5].Value
}
else {
$event.Properties[1].Value
}
if ($ExcludeSystemAccounts) {
if ($userName -in @(
'SYSTEM',
'LOCAL SERVICE',
'NETWORK SERVICE',
'ANONYMOUS LOGON'
)) {
continue
}
if (
$userName -like 'DWM-*' -or
$userName -like 'UMFD-*'
) {
continue
}
}
[PSCustomObject]@{
TimeStamp = $event.TimeCreated
EventType = $(
if ($event.Id -eq '4624') {
'LogOn'
}
else {
'LogOff'
}
)
User = $userName
SourceIP = $(
if ($event.Id -eq '4624') {
$event.Properties[18].Value
}
else {
$null
}
)
ComputerName = $ComputerName
LogOnType = $(
if ($event.Id -eq 4624) {
$logOnTypeTable["$($event.Properties[8].Value)"]
}
elseif ($event.Id -eq 4634) {
$logOnTypeTable["$($event.Properties[4].Value)"]
}
)
}
}
}
catch {
Write-Error $_.Exception.Message
}
Keep in mind that the script uses EventData property indexes based on the current Windows Security event schema. For scripts that must support multiple Windows versions and future Windows releases, we recommend XML-based event field extraction.
How to use this script?
Several optional script parameters are available:
- -Username – get logon events for a specific user.
- -StartTime
- -EndTime
- -IncludeLogOff – switch specifies whether to print logout events (by default only user login activity is checked).
- -ComputerName – query remote computer event logs (requires RPC connectivity). By default, local computer logs are fetched.
- -ExcludeSystemAccounts – excludes SYSTEM, LOCAL SERVICE, NETWORK SERVICE, ANONYMOUS LOGON, DWM-* and UMFD-* accounts from the report.
Here are some examples of how to use the script:
- List logon events on a local computer:
.\Get-LogOnHistory.ps1
- To return only real user logon activity and hide common Windows service and virtual accounts:
.\Get-LogOnHistory.ps1 -ExcludeSystemAccounts
- Get a history of specific user logon and logoff activity:
.\Get-LogOnHistory.ps1 -Username speed.racer -IncludeLogOff
- View the user’s logon history on a remote computer:
.\Get-LogOnHistory.ps1 -Username superadmin -ComputerName theitbrosdc1

Output includes logon history with LogOnType, date/time, account name, hostname, and source IP address for remote logons.
To get logon history for a specific date range, use the following command (it returns logon events that occurred between November 1 and November 30, 2024):
.\Get-LogOnHistory.ps1 `
-StartTime "2024-11-01" `
-EndTime "2024-11-30"
Note. When you run this script against a DC, the results may include authentication-related events that do not represent actual user logons. You should review the LogOnType value carefully before drawing conclusions about user activity.
Export Login History to CSV
The script returns PowerShell objects, which means you can easily export the results to a CSV file for reporting/further analysis in Microsoft Excel.
For example, in order to export all logon events to a CSV file, use the command below:
.\Get-LogOnHistory.ps1 |
Export-Csv C:\Temp\Logons.csv -NoTypeInformation
You can also export filtered results. For example, to export logon and logoff activity for a specific user, run the command:
.\Get-LogOnHistory.ps1 `
-Username speed.racer `
-IncludeLogOff |
Export-Csv C:\Temp\SpeedRacer-Logons.csv -NoTypeInformation
The generated CSV file can be opened in Excel/imported into reporting and SIEM tools for further analysis.
Note. Windows stores logon history only as long as the corresponding events remain in the Security log. On busy servers and DCs, older events may be overwritten quickly if the Security log size is too small. You should consider increasing log size/forwarding security events to a SIEM for long-term retention.
Collecting Logon Events from Multiple Machines
In larger environments, in case if you query individual machines separately, that will take a lot of time and usually is not practical.
For enterprise-scale logon auditing, you can use Windows Event Forwarding (WEF)/SIEM platforms in order to collect Security events from multiple devices into a centralized location. In large AD environments, logon auditing is usually centralized using Windows Event Forwarding/SIEM solutions (such as Microsoft Sentinel, Splunk, or Microsoft Defender XDR). Querying each workstation individually is mainly useful for troubleshooting/small environments.
If you only need to query several machines, you can also run the script against multiple hosts by using PowerShell remoting/by iterating through a list of computer names.
Here is an example:
Note. Accessing Security logs on remote machines typically requires admin privileges.
$computers = @(
'PC01',
'PC02',
'PC03'
)
foreach ($computer in $computers) {
.\Get-LogOnHistory.ps1 -ComputerName $computer
}
How can I enable user logon auditing in Windows?
You can enable logon auditing through Group Policy. Go to Computer Configuration → Policies → Windows Settings → Security Settings → Advanced Audit Policy Configuration → Audit Policies → Logon/Logoff. Here you need to enable:
- Audit Logon (Success and optionally Failure)
- Audit Logoff (Success)
After applying the policy, update clients with gpupdate command.
Which Event IDs are used to track user logons and logoffs?
The most commonly used events are:
| Event ID | Description |
|---|---|
| 4624 | Successful logon |
| 4625 | Failed logon |
| 4634 | Logoff |
| 4647 | User-initiated logoff |
| 4672 | Special privileges assigned to a logon |
| 4648 | Logon using explicit credentials |
| 4776 | NTLM authentication |
| 4768 | Kerberos TGT request |
| 4769 | Kerberos service ticket request |
What do the common Windows Logon Types mean?
The most important logon types are:
| Logon Type | Meaning |
|---|---|
| 2 | Interactive (local console login) |
| 3 | Network |
| 4 | Batch |
| 5 | Service |
| 7 | Unlock workstation |
| 8 | NetworkCleartext |
| 9 | NewCredentials |
| 10 | RemoteInteractive (RDP) |
| 11 | CachedInteractive |
Why is Event ID 4624 not always a real user sign-in?
On domain controllers and busy servers, Event ID 4624 can be generated by:
- Kerberos authentication
- NTLM authentication
- LDAP binds
- Computer account authentication
- Service logons
- Network access events
Always review the Logon Type and account name before treating an event as an actual user login.
How long does Windows keep logon history?
Windows stores logon history only while the corresponding events remain in the Security log. On busy servers and domain controllers, older events may be overwritten quickly if the log size is too small.
For long-term retention, consider:
- Increasing Security log size
- Windows Event Forwarding (WEF)
- Microsoft Sentinel
- Splunk
- Microsoft Defender XDR
- Other SIEM platforms


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)
Hello, this is very helpful. I was curious if it is possible to filter by logon type in the event you were only interested in a certain type?