Recently, I was working on a security audit project where I needed to retrieve the login history of all users on a Windows server without installing third-party tools.
In this tutorial, I will explain several methods to retrieve user login history using PowerShell commands. These approaches will help system administrators, security professionals, or anyone who needs to monitor user activity on Windows computers.
Let us check these methods.
Method 1: Using the Security Event Log
The Windows Security Event Log contains valuable information about user logon and logoff events. Here’s how you can access this information with PowerShell:
Get-EventLog -LogName Security -InstanceId 4624 |
Where-Object {$_.ReplacementStrings[5] -notlike "*$*"} |
Select-Object TimeGenerated,
@{Name='Username';Expression={$_.ReplacementStrings[5]}},
@{Name='Domain';Expression={$_.ReplacementStrings[6]}},
@{Name='LogonType';Expression={$_.ReplacementStrings[8]}} |
Sort-Object TimeGenerated -DescendingThis command retrieves Event ID 4624 (successful login) events from the Security log, filters out system accounts (which typically contain dollar signs), and displays the time, username, domain, and logon type.
You can see the exact output in the screenshot below:

For more recent Windows versions, you can use the newer Get-WinEvent cmdlet:
Get-WinEvent -FilterHashtable @{
LogName = 'Security'
Id = 4624
} -MaxEvents 50 |
Where-Object {$_.Properties[5].Value -notlike "*$*"} |
Select-Object TimeCreated,
@{Name='Username';Expression={$_.Properties[5].Value}},
@{Name='Domain';Expression={$_.Properties[6].Value}},
@{Name='LogonType';Expression={$_.Properties[8].Value}} |
Sort-Object TimeCreated -DescendingCheck out Show Logged-In Users with PowerShell
Method 2: Using the Windows Management Instrumentation (WMI)
WMI provides another approach to retrieve user login information using PowerShell. Here is the complete PowerShell script.
Get-WmiObject Win32_LogonSession |
ForEach-Object {
$logonId = $_.LogonId
$user = Get-WmiObject Win32_LoggedOnUser |
Where-Object {$_.Dependent.ToString() -match "Domain=\"(.*)\",Name=\"(.*)\",LogonId=\"$logonId\""} |
Select-Object -First 1
if ($user) {
$matches = $user.Dependent.ToString() |
Select-String -Pattern "Domain=\"(.*)\",Name=\"(.*)\"" |
Select-Object -ExpandProperty Matches
[PSCustomObject]@{
Username = $matches.Groups[2].Value
Domain = $matches.Groups[1].Value
LogonId = $logonId
StartTime = [System.Management.ManagementDateTimeConverter]::ToDateTime($_.StartTime)
LogonType = switch ($_.LogonType) {
2 {"Interactive"}
3 {"Network"}
4 {"Batch"}
5 {"Service"}
7 {"Unlock"}
8 {"NetworkCleartext"}
9 {"NewCredentials"}
10 {"RemoteInteractive"}
11 {"CachedInteractive"}
default {"Unknown"}
}
}
}
} | Sort-Object StartTime -DescendingThis approach gives you detailed information about each logon session, including the logon type in a human-readable format.
Check out Set the Default Printer Using PowerShell in Windows
Method 3: Creating a User Login History Report
If you need a comprehensive report of user logins over the past few days, this script will create a CSV file with the information:
$days = 7
$logPath = "$env:USERPROFILE\Desktop\UserLoginHistory.csv"
# Get events from the Security log
$events = Get-WinEvent -FilterHashtable @{
LogName = 'Security'
Id = 4624
StartTime = (Get-Date).AddDays(-$days)
} -ErrorAction SilentlyContinue |
Where-Object {$_.Properties[5].Value -notlike "*$*" -and $_.Properties[8].Value -eq 2 -or $_.Properties[8].Value -eq 10}
# Process the events
$loginData = foreach ($event in $events) {
[PSCustomObject]@{
Time = $event.TimeCreated
User = "$($event.Properties[6].Value)\$($event.Properties[5].Value)"
LoginType = if($event.Properties[8].Value -eq 2){"Local"}else{"Remote"}
WorkstationName = $event.Properties[11].Value
IPAddress = $event.Properties[18].Value
}
}
# Export to CSV
$loginData | Sort-Object Time -Descending | Export-Csv -Path $logPath -NoTypeInformation
Write-Host "Login history for the past $days days has been exported to $logPath"This script generates a report containing login time, username, login type (local or remote), workstation name, and IP address for each login event.
Check out Set Password for Local User in Windows 11 Using PowerShell
Method 4: Monitoring Remote Computer Login History
If you need to check the login history on a remote computer, you can use the following script:
$computerName = "REMOTE-PC"
$credentials = Get-Credential -Message "Enter admin credentials for $computerName"
$events = Invoke-Command -ComputerName $computerName -Credential $credentials -ScriptBlock {
Get-WinEvent -FilterHashtable @{
LogName = 'Security'
Id = 4624
StartTime = (Get-Date).AddDays(-3)
} -ErrorAction SilentlyContinue |
Where-Object {$_.Properties[5].Value -notlike "*$*"} |
Select-Object TimeCreated,
@{Name='Username';Expression={$_.Properties[5].Value}},
@{Name='Domain';Expression={$_.Properties[6].Value}},
@{Name='LogonType';Expression={$_.Properties[8].Value}},
@{Name='IPAddress';Expression={$_.Properties[18].Value}}
}
$events | Sort-Object TimeCreated -Descending | Format-Table -AutoSizeThis script uses the Invoke-Command cmdlet to execute the command on a remote computer, which is perfect for administrators who need to check multiple machines.
Read Set the Time Zone Using PowerShell in Windows
Find Failed Login Attempts
Security professionals often need to identify failed login attempts, which might indicate brute force attacks:
$failedLogins = Get-WinEvent -FilterHashtable @{
LogName = 'Security'
Id = 4625
StartTime = (Get-Date).AddDays(-1)
} -ErrorAction SilentlyContinue
$failedData = foreach ($event in $failedLogins) {
[PSCustomObject]@{
Time = $event.TimeCreated
Username = $event.Properties[5].Value
Domain = $event.Properties[6].Value
Reason = switch ($event.Properties[8].Value) {
"0xc000006a" {"Invalid username or password"}
"0xc0000234" {"Account locked"}
"0xc0000072" {"Account disabled"}
"0xc000006f" {"Time restriction violation"}
"0xc0000070" {"Workstation restriction violation"}
"0xc0000193" {"Account expiration"}
"0xc0000071" {"Password expired"}
default {"Unknown failure reason: $($event.Properties[8].Value)"}
}
SourceIP = $event.Properties[19].Value
SourceWorkstation = $event.Properties[13].Value
}
}
$failedData | Sort-Object Time -Descending | Format-Table -AutoSizeThis script retrieves failed login attempts from the past 24 hours and translates the failure codes into human-readable explanations, making it easy to identify patterns or potential security threats.
Check out Check for Windows Updates Using PowerShell
Understanding Logon Types
When reviewing login events, you’ll notice different logon types. Here’s what they mean:
- Type 2: Interactive (local logon)
- Type 3: Network (accessing shared folder)
- Type 4: Batch (scheduled task)
- Type 5: Service (service startup)
- Type 7: Unlock (workstation unlock)
- Type 8: NetworkCleartext (most likely IIS with basic authentication)
- Type 9: NewCredentials (RunAs command)
- Type 10: RemoteInteractive (RDP)
- Type 11: CachedInteractive (logging on to a cached domain account when DC is not available)
In this tutorial, I have explained how to retrieve and analyze user login information on Windows systems using PowerShell.
For daily monitoring, a scheduled task running the report script would be ideal, while the WMI method is perfect for real-time investigation of current sessions.
Remember that accessing security logs typically requires administrative privileges, so make sure you’re running PowerShell as an administrator when executing these commands.
I hope you found this article helpful. If you have any questions or suggestions, please feel free to leave them in the comments below.
You may also like:
- Get Windows Update History Using PowerShell
- Monitor and Manage CPU Usage using Windows PowerShell
- Disable Windows Defender Using PowerShell
Bijay Kumar is an esteemed author and the mind behind PowerShellFAQs.com, where he shares his extensive knowledge and expertise in PowerShell, with a particular focus on SharePoint projects. Recognized for his contributions to the tech community, Bijay has been honored with the prestigious Microsoft MVP award. With over 15 years of experience in the software industry, he has a rich professional background, having worked with industry giants such as HP and TCS. His insights and guidance have made him a respected figure in the world of software development and administration. Read more.