Reputation: 101
How does one read logon and logoff events from the Windows event log, and retrieve the corresponding information for each user from Active Directory, using Powershell?
Upvotes: 3
Views: 9796
Reputation: 2929
With Windows 10 professional, a member of Active Directory domain, this script will generate a list of logon / logoff times for the selected user, includes events from screensaver lockscreen. Powershell script to log active work hours, no application needed.
# original source: https://community.spiceworks.com/topic/764481-get-logon-off-workstation-lock-unlock-times
# cleaned up, filtered by username, and included lock by screensaver timeout by kevin, Dec 2018
# must enable auditing via secpol.msc
# Security Settings -> Advanced Audit Policy -> System Audit -> Logon/Logoff -> Audit Other Logon/Off Events -> On Success
$days = 30
$username = "kevin"
Write-Host "Retrieving last $days days of user: $username, logon/logoff activity... please wait
$events = @()
$events += Get-WinEvent -FilterHashtable @{
LogName='Security'
Id=@(4624,4800,4634)
StartTime=(Get-Date).AddDays(-$days)
}
$type_lu = @{
4624 = 'Logon'
4800 = 'Logoff' # screensaver lock
4634 = 'Logoff' # explicit
}
$ns = @{'ns'='http://schemas.microsoft.com/win/2004/08/events/event'}
$target_xpath = "//ns:Data[@Name='TargetUserName']"
$usersid_xpath = "//ns:Data[@Name='UserSid']"
If($events) {
$results = ForEach($event in $events) {
$xml = $event.ToXml()
Switch -Regex ($event.Id) {
'4...' {
$user = (
Select-Xml -Content $xml -Namespace $ns -XPath $target_xpath
).Node.'#text'
Break
}
'7...' {
$sid = (
Select-Xml -Content $xml -Namespace $ns -XPath $usersid_xpath
).Node.'#text'
$user = (
New-Object -TypeName 'System.Security.Principal.SecurityIdentifier' -ArgumentList $sid
).Translate([System.Security.Principal.NTAccount]).Value
Break
}
}
if($username -eq $user) {
New-Object -TypeName PSObject -Property @{
Time = $event.TimeCreated
Id = $event.Id
Type = $type_lu[$event.Id]
User = $user
}
}
}
If($results) {
$results
}
}
Example output:
C:\WINDOWS\system32>powershell -file C:\desk\path\timetracker.ps1
Retrieving last 10 days of user: kevin, logon/logoff activity
Time User Id Type
---- ---- -- ----
12/4/2018 1:39:22 PM kevin 4634 Logoff
12/4/2018 1:39:19 PM kevin 4800 Logoff
12/4/2018 1:10:28 PM kevin 4634 Logoff
12/4/2018 1:10:28 PM kevin 4624 Logon
12/4/2018 12:57:32 PM kevin 4634 Logoff
12/4/2018 12:57:32 PM kevin 4624 Logon
12/4/2018 12:29:43 PM kevin 4624 Logon
12/4/2018 11:48:11 AM kevin 4634 Logoff
To debug this script, I opened Event Viewer eventvwr.msc, and used this custom filter (XML).
<QueryList>
<Query Id="0" Path="Security">
<Select Path="Security">*[System[(EventID=4624)] and EventData[Data[@Name='TargetUserName']='kevin']]</Select>
</Query>
</QueryList>
Powershell also has Get-EventLog cmdlet, but I found it lacking in options.
Upvotes: 0
Reputation: 101
The following script will read Winlogon events from the System log, retrieve information from AD based on each user's SID, and display the results in a generated HTML page. The results of each AD lookup are cached to prevent unnecessary round-trips to the AD server.
# event id 7001 is Logon, event id 7002 is Logoff
function WinlogonEventIdToString($EventID) {switch($EventID){7001{"Logon";break}7002{"Logoff";break}}}
# look up SID in Active Directory and cache the results in a hashtable
$AdUsers = @{}
function SidToAdUser($sid) {
$AdUser = $AdUsers[$sid]
if ($AdUser -eq $null) {
$AdUser = $AdUsers[$sid] = [adsi]("LDAP://<SID=" + $sid + ">")
}
return $AdUser
}
$outputFilename = [System.IO.Path]::GetTempPath() + "DisplayLatestLogonEvents.html"
# the first Select extracts the SID from the event log entry and converts the event id to a descriptive string
# the second Select is responsible for looking up the User object in Active Directory, using the SID
# the final Select picks the various attribute data from the User object, ready for display in the table
# to retrieve only recent log entries, one can use something like this in Get-EventLog: -After (Get-Date).AddDays(-14)
Get-Eventlog -Logname "System" -Source "Microsoft-Windows-Winlogon" -InstanceId 7001,7002 `
| Select TimeGenerated, @{n='Operation';e={WinlogonEventIdToString $_.EventID}}, @{n='SID';e={$_.ReplacementStrings[1]}} `
| Select TimeGenerated, Operation, @{n='AdUser';e={(SidToAdUser $_.SID)}} `
| Select TimeGenerated, Operation, `
@{n='Username';e={$_.AdUser.sAMAccountName}}, `
@{n='Full name';e={$_.AdUser.firstname + " " + $_.AdUser.lastname}}, `
@{n='Title';e={$_.AdUser.title}}, `
@{n='Department';e={$_.AdUser.department}}, `
@{n='Company';e={$_.AdUser.company}} `
| ConvertTo-HTML -Head "<style>td, th { border:1px solid grey }</style>" | Out-File $outputFilename
# this will open the default web browser
Invoke-Expression $outputFilename
Upvotes: 6