There are several different tools to get information about the time of a user logon to an Active Directory domain. The time of the last successful user authentication in an AD domain may be obtained from the user lastLogon attribute it is only updated on the domain controller on which the user is authenticated) or lastLogonTimpestamp attribute (it is replicated between the DCs in a domain, but only in 14 days by default). You can check the value of the user attribute using the AD attribute editor or with the Get-ADUser PowerShell cmdlet. However, sometimes you may want to view the history of user activity (logons) in a domain for a long period of time.
You can get information about successful user logon (authentication) events from the domain controller logs. In this article we will show how to track user logon history in the domain using PowerShell. This way you can get a complete history of user activity in the domain, the time when a user starts working and logon computers.
Active Directory User Logon Audit Policy
In order the information about successful/failed logon to be collected in the domain controller logs, enable the audit policy of user logon events.
- Open the domain GPO management console (
GPMC.msc
); - Open the Default Domain Policy GPO settings and go to Computer Configuration -> Policies -> Windows Settings -> Security Settings –> Advanced Audit Policy Configuration -> Audit Policies -> Logon/Logoff;
- Enable two audit policies (Audit Logon and Audit Other Logon/Logoff Events). Select Success and Failure options in the audit policy settings to register both successful and failed logons in the Security log on the DCs and computers;
- Save the changes in GPO and update the policy settings on your domain controllers using the following command: gpupdate /force (or wait for 90 minutes, DC replication time is not taken into account).
When a user logons to any computer in Active Directory domain, an event with the Event ID 4624 (An account was successfully logged on) appears in the log of the domain controller that has authenticated the user (Logon Server). A successfully authenticated account (Account name), a computer name (Workstation name) or an IP address (Source Network Address) of a computer used to logon are shown in the event description.
Also, you need to check the value of the Logon Type field. We are interested in the following codes:
- Logon Type 10 – Remote Interactive logon – a logon using RDP, shadow connection or Remote Assistance (this event may appear on a domain controller if an administrator or non-admin user having RDP access permission on DC logs on). This event is used to monitor and analyze the activity of Remote Desktop Services users.
- Logon Type 3 – Network logon (used when a user is authenticated on a DC and connects to a shared folder, printer or IIS service)
Also you can track a Kerberos ticket issue event when authenticating a user. The Event ID 4768 is A Kerberos authentication ticket (TGT) was requested. To do it, enable the event audit in the policy Account Logon –> Audit Kerberos Authentication Service -> Success and Failure.
The event 4768 also contains a name (IP address) of a computer and a user account (Account Name or User ID) that received a Kerberos ticket (has been authenticated).
Getting User Last Logon History with PowerShell
You can use the Get-Eventlog PowerShell cmdlet to get all events from the domain controller’s event logs, filter them by the EventID you want, and display information about the time when a user authenticated in the domain and a computer used to logon. Since there may be multiple domain controllers in your domain and you may want to get a user logon history from each of them, use the Get-ADDomainController cmdlet (from the AD module for Windows PowerShell). The cmdlet allows to get the list of all DCs in your domain.
The following PowerShell script allows you to get all logon events for a user to an AD domain from all domain controllers. As a result, you will get a table with the user logon history and computers a user authenticated from.
# a username, whose logon history you want to view
$checkuser='*jbrown*'
# getting information about the user logon history for the last 2 days (you can change this value)
$startDate = (get-date).AddDays(-2)
$DCs = Get-ADDomainController -Filter *
foreach ($DC in $DCs){
$logonevents = Get-Eventlog -LogName Security -InstanceID 4624 -after $startDate -ComputerName $dc.HostName
foreach ($event in $logonevents){
if (($event.ReplacementStrings[5] -notlike '*$') -and ($event.ReplacementStrings[5] -like $checkuser)) {
# Remote (Logon Type 10)
if ($event.ReplacementStrings[8] -eq 10){
write-host "Type 10: Remote Logon`tDate: "$event.TimeGenerated "`tStatus: Success`tUser: "$event.ReplacementStrings[5] "`tWorkstation: "$event.ReplacementStrings[11] "`tIP Address: "$event.ReplacementStrings[18] "`tDC Name: " $dc.Name
}
# Network(Logon Type 3)
if ($event.ReplacementStrings[8] -eq 3){
write-host "Type 3: Network Logon`tDate: "$event.TimeGenerated "`tStatus: Success`tUser: "$event.ReplacementStrings[5] "`tWorkstation: "$event.ReplacementStrings[11] "`tIP Address: "$event.ReplacementStrings[18] "`tDC Name: " $dc.Name
}
}
}
}
Get Domain User Logon History Based on Kerberos Events
You can also get a user authentication history in the domain based on the event of a Kerberos ticket issue (TGT Request — EventID 4768). In this case, less events will be displayed in the output (network logons are excluded, as well as access events to the DC folders during getting GPO files or running logon scripts). The following PowerShell script will display the information about all user logons for the last 24 hours:
$alluserhistory = @()
$startDate = (get-date).AddDays(-1)
$DCs = Get-ADDomainController -Filter *
foreach ($DC in $DCs){
$logonevents = Get-Eventlog -LogName Security -InstanceID 4768 -after $startDate -ComputerName $dc.HostName
foreach ($event in $logonevents){
if ($event.ReplacementStrings[0] -notlike '*$') {
$userhistory = New-Object PSObject -Property @{
UserName = $event.ReplacementStrings[0]
IPAddress = $event.ReplacementStrings[9]
Date = $event.TimeGenerated
DC = $dc.Name
}
$alluserhistory += $userhistory
}
}
}
$alluserhistory
Note that in this case you won’t see any logon events of the users authenticated from clients or apps that use NTLM instead of Kerberos.
4 comments
Second script does not display anything
For first script, how to save out to a csv file.
| export-csv
When a user logs on to a Windows computer, 4624 event logs occur. However, in many cases, including connecting over a network, remote desktop connection, and unlocking the locked computer, event 4624 is still logged. The following table can be viewed as the types of logins (Logon Type) :
Logotype Logo Title Description
0 System It is only used for the “System” account.
2 Interactive Actual login event.
3 Network Network login. For example, accessing a share.
4 Batch Batch logon type is used by batch servers, where processes may be executing on behalf of a user without their direct intervention.
5 Service A record of a service started by the Service Control Manager.
7 Unlock Record of unlocking the locked computer.
8 NetworkCleartext A user is logged on over the network, but the password was sent explicitly, not as a hash.
9 NewCredentials The token generated at login was reused but specified new login information (username and password).
10 RemoteInteractive Connection to remote desktop established.
11 CachedInteractive The domain server (DC) was not consulted to verify the password at login, the local registration information (cache) was used.
12 CachedRemoteInteractive Same as RemoteInteractive, tried(?) for internal monitoring
13 CachedUnlock I guess it’s the case of using local cache information without consulting DC when unlocking.
If we are looking for logins to a non-domain computer we should look at 2 or 7. For a domain member computer, it can be 2, 11, and 13.
With a Get-WinEvent query like this, it will most likely not be possible to see all the information in the event body:
PS> Get-WinEvent -Filterhashtable @{LogName=”Security”;Id=4624}
Instead, it is possible to take into account the login type and produce a better output with the EventProperty object. Here are the EventProperty members for event 4624:
0 : Subject User SID
1 : Subject Username
2 : Subject Domain Name
3 : Subject Logon Id
4 : Target User SID
5 : Target Username
6 : Target Domain Name
7 : Target Logon Id
8 : Logon Type
9 : Logon Process Name
10: Authentication Package Name
11: Workstation Name
12: Logon GUID
13: Transmitted Services
14: LmPackageName
15: Keylength
16: ProcessId
17: ProcessName
18: IP Address
19: IP Port
20: Impersonation Level
21: Restricted Admin Mode
22: Target Outbound Username
23: Target Outbound Domain Name
24: Virtual Account
25: Target Linked Logon Id
26: Elevated Token
The following details are given for member Status 4 in the EventProperty object of the 4771 Pre-Authentication failed error :
status Kerberos RFC definition Explanation
0x1 Client’s entry in database has expired
0x2 Server’s entry in database has expired
0x3 Requested protocol version # not supported
0x4 Client’s key encrypted in old master key
0x5 Server’s key encrypted in old master key
0x6 Client not found in Kerberos database Bad user name, or new computer/user account has not replicated to DC yet
0x7 Server not found in Kerberos database New computer account has not replicated yet or computer is pre-w2k
0x8 Multiple principal entries in database
0x9 The client or server has a null key administrator should reset the password on the account
0xA Ticket not eligible for postdating
0xB Requested start time is later than end time
0xC KDC policy rejects request Workstation restrictions
0xD KDC cannot accommodate requested option
0xE KDC has no support for encryption type
0xF KDC has no support for checksum type
0x10 KDC has no support for padata type
0x11 KDC has no support for transited type
0x12 Clients credentials have been revoked The account is inactive, expired, locked, or out of sign-in hours.
0x13 Credentials for server have been revoked
0x14 TGT has been revoked
0x15 Client not yet valid – try again later
0x16 Server not yet valid – try again later
0x17 Password has expired The password has expired
0x18 Pre-authentication information was invalid Often wrong password
0x19 Additional pre-authentication required*
0x1F Integrity check on decrypted field failed
0x20 ticket expired Frequently logged by computer accounts
0x21 Ticket not yet valid
0x21 Ticket not yet valid
0x22 Request is a replay
0x23 The ticket isn’t for us
0x24 Ticket and authenticator don’t match
0x25 Clock skew too great Workstation’s clock too far out of sync with the DC’s
0x26 Incorrect net address IP address change?
0x27 Protocol version mismatch
0x28 Invalid msg type
0x29 Message stream modified
0x2A Message out of order
0x2C Specified version of key is not available
0x2D Service key not available
0x2E Mutual authentication failed may be a memory allocation failure
0x2F Incorrect message direction
0x30 Alternative authentication method required*
0x31 Incorrect sequence number in message
0x32 Inappropriate type of checksum in message
0x3C Generic error (description in e-text)
0x3D Field is too long for this implementation
Using these, a command like this is possible for a more shaped output:
PS> Get-WinEvent -FilterHashtable @{LogName=”Security”;Id=4624} |
Where-Object {$_.properties[8].Value -eq 2} |
Select-Object TimeCreated, Id, @{Name=”Username”;Expression={$_.properties[5].Value}}, @{Name=”LogonProcName”;Expression={$_.properties[9].Value }}, @{Name=”AuthPkgName”;Expression={$_.properties[10].Value}}, @{Name=”IPAddress”;Expression={$_.properties[18].Value}}
Logout event 4634, login failure (wrong password/username) can be queried with events 4625. There are 5 fields in the EventProperties object for logout. In 4625, there are fields in number and quality similar to 4624.