How to read logon events and lookup user information, using Powershell?

active-directory, authentication, event-log, powershell, winlogon

Solution

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

Problem

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?

Original source