Add DisplayName lookup from AD
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
Queries Domain Controller security event logs for logon events (4624)
|
Queries Domain Controller security event logs for logon events (4624)
|
||||||
to determine which computer each user last authenticated from.
|
to determine which computer each user last authenticated from.
|
||||||
Resolves IP addresses to computer names for network logons.
|
Resolves IP addresses to computer names and looks up user display names.
|
||||||
|
|
||||||
.PARAMETER OutputPath
|
.PARAMETER OutputPath
|
||||||
Path for the output CSV file. Defaults to current directory.
|
Path for the output CSV file. Defaults to current directory.
|
||||||
@@ -14,11 +14,11 @@
|
|||||||
.PARAMETER DaysBack
|
.PARAMETER DaysBack
|
||||||
Number of days of event logs to search. Default is 7.
|
Number of days of event logs to search. Default is 7.
|
||||||
|
|
||||||
.PARAMETER IncludeNetworkLogons
|
.PARAMETER ExcludeNetworkLogons
|
||||||
Include Type 3 (Network) logons. Default is true.
|
Exclude Type 3 (Network) logons. Default includes them.
|
||||||
|
|
||||||
.PARAMETER ResolveIPs
|
.PARAMETER SkipIPResolve
|
||||||
Attempt to resolve IP addresses to hostnames. Default is true.
|
Skip IP to hostname resolution. Faster but less useful.
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
.\Get-UserLastLogonComputer.ps1
|
.\Get-UserLastLogonComputer.ps1
|
||||||
@@ -66,6 +66,8 @@ $StartDate = (Get-Date).AddDays(-$DaysBack)
|
|||||||
|
|
||||||
# Cache for IP to hostname resolution
|
# Cache for IP to hostname resolution
|
||||||
$IPCache = @{}
|
$IPCache = @{}
|
||||||
|
# Cache for user display names
|
||||||
|
$UserCache = @{}
|
||||||
|
|
||||||
function Resolve-IPToHostname {
|
function Resolve-IPToHostname {
|
||||||
param([string]$IP)
|
param([string]$IP)
|
||||||
@@ -74,20 +76,16 @@ function Resolve-IPToHostname {
|
|||||||
return $null
|
return $null
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check cache first
|
|
||||||
if ($IPCache.ContainsKey($IP)) {
|
if ($IPCache.ContainsKey($IP)) {
|
||||||
return $IPCache[$IP]
|
return $IPCache[$IP]
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
# Try DNS reverse lookup
|
|
||||||
$hostname = [System.Net.Dns]::GetHostEntry($IP).HostName
|
$hostname = [System.Net.Dns]::GetHostEntry($IP).HostName
|
||||||
# Extract just the computer name (before the domain)
|
|
||||||
$computerName = ($hostname -split '\.')[0].ToUpper()
|
$computerName = ($hostname -split '\.')[0].ToUpper()
|
||||||
$IPCache[$IP] = $computerName
|
$IPCache[$IP] = $computerName
|
||||||
return $computerName
|
return $computerName
|
||||||
} catch {
|
} catch {
|
||||||
# Try querying AD for the IP
|
|
||||||
try {
|
try {
|
||||||
$computer = Get-ADComputer -Filter "IPv4Address -eq '$IP'" -Properties Name -ErrorAction SilentlyContinue
|
$computer = Get-ADComputer -Filter "IPv4Address -eq '$IP'" -Properties Name -ErrorAction SilentlyContinue
|
||||||
if ($computer) {
|
if ($computer) {
|
||||||
@@ -101,6 +99,27 @@ function Resolve-IPToHostname {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Get-UserDisplayName {
|
||||||
|
param([string]$Username, [string]$Domain)
|
||||||
|
|
||||||
|
$UserKey = "$Domain\$Username"
|
||||||
|
|
||||||
|
if ($UserCache.ContainsKey($UserKey)) {
|
||||||
|
return $UserCache[$UserKey]
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$User = Get-ADUser -Identity $Username -Properties DisplayName -ErrorAction SilentlyContinue
|
||||||
|
if ($User -and $User.DisplayName) {
|
||||||
|
$UserCache[$UserKey] = $User.DisplayName
|
||||||
|
return $User.DisplayName
|
||||||
|
}
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
$UserCache[$UserKey] = ''
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Write-Host "Retrieving logon events from Security log..." -ForegroundColor Yellow
|
Write-Host "Retrieving logon events from Security log..." -ForegroundColor Yellow
|
||||||
|
|
||||||
@@ -128,7 +147,6 @@ try {
|
|||||||
|
|
||||||
$LogonType = [int]($xml.Event.EventData.Data | Where-Object { $_.Name -eq 'LogonType' }).'#text'
|
$LogonType = [int]($xml.Event.EventData.Data | Where-Object { $_.Name -eq 'LogonType' }).'#text'
|
||||||
|
|
||||||
# Skip if not a logon type we want
|
|
||||||
if ($LogonType -notin $LogonTypes) { continue }
|
if ($LogonType -notin $LogonTypes) { continue }
|
||||||
|
|
||||||
$Username = ($xml.Event.EventData.Data | Where-Object { $_.Name -eq 'TargetUserName' }).'#text'
|
$Username = ($xml.Event.EventData.Data | Where-Object { $_.Name -eq 'TargetUserName' }).'#text'
|
||||||
@@ -143,7 +161,7 @@ try {
|
|||||||
if ($Domain -in @('Window Manager', 'Font Driver Host', 'NT AUTHORITY')) { continue }
|
if ($Domain -in @('Window Manager', 'Font Driver Host', 'NT AUTHORITY')) { continue }
|
||||||
if ([string]::IsNullOrWhiteSpace($Username)) { continue }
|
if ([string]::IsNullOrWhiteSpace($Username)) { continue }
|
||||||
|
|
||||||
# Determine computer name - try WorkstationName first, then resolve IP
|
# Determine computer name
|
||||||
$Computer = $null
|
$Computer = $null
|
||||||
if (-not [string]::IsNullOrWhiteSpace($Workstation) -and $Workstation -ne '-') {
|
if (-not [string]::IsNullOrWhiteSpace($Workstation) -and $Workstation -ne '-') {
|
||||||
$Computer = $Workstation.ToUpper()
|
$Computer = $Workstation.ToUpper()
|
||||||
@@ -152,7 +170,6 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ([string]::IsNullOrWhiteSpace($Computer)) {
|
if ([string]::IsNullOrWhiteSpace($Computer)) {
|
||||||
# Store IP if we couldn't resolve
|
|
||||||
if (-not [string]::IsNullOrWhiteSpace($IPAddress) -and $IPAddress -ne '-') {
|
if (-not [string]::IsNullOrWhiteSpace($IPAddress) -and $IPAddress -ne '-') {
|
||||||
$Computer = "[$IPAddress]"
|
$Computer = "[$IPAddress]"
|
||||||
} else {
|
} else {
|
||||||
@@ -168,6 +185,7 @@ try {
|
|||||||
$UserLogons[$UserKey] = [PSCustomObject]@{
|
$UserLogons[$UserKey] = [PSCustomObject]@{
|
||||||
Domain = $Domain
|
Domain = $Domain
|
||||||
Username = $Username
|
Username = $Username
|
||||||
|
DisplayName = '' # Will populate after
|
||||||
Computer = $Computer
|
Computer = $Computer
|
||||||
IPAddress = if ($IPAddress -and $IPAddress -ne '-') { $IPAddress } else { '' }
|
IPAddress = if ($IPAddress -and $IPAddress -ne '-') { $IPAddress } else { '' }
|
||||||
LogonTime = $LogonTime
|
LogonTime = $LogonTime
|
||||||
@@ -183,6 +201,13 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Write-Host "Processed $ProcessedCount matching logon events." -ForegroundColor Yellow
|
Write-Host "Processed $ProcessedCount matching logon events." -ForegroundColor Yellow
|
||||||
|
Write-Host "Looking up display names for $($UserLogons.Count) users..." -ForegroundColor Yellow
|
||||||
|
|
||||||
|
# Populate display names
|
||||||
|
foreach ($Key in $UserLogons.Keys) {
|
||||||
|
$User = $UserLogons[$Key]
|
||||||
|
$User.DisplayName = Get-UserDisplayName -Username $User.Username -Domain $User.Domain
|
||||||
|
}
|
||||||
|
|
||||||
$Results = $UserLogons.Values | Sort-Object Domain, Username
|
$Results = $UserLogons.Values | Sort-Object Domain, Username
|
||||||
|
|
||||||
@@ -192,7 +217,7 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Export to CSV
|
# Export to CSV
|
||||||
$Results | Select-Object Domain, Username, Computer, IPAddress, LogonTime, LogonType |
|
$Results | Select-Object Domain, Username, DisplayName, Computer, IPAddress, LogonTime, LogonType |
|
||||||
Export-Csv -Path $CsvFile -NoTypeInformation -Encoding UTF8
|
Export-Csv -Path $CsvFile -NoTypeInformation -Encoding UTF8
|
||||||
|
|
||||||
Write-Host "`n===== Results =====" -ForegroundColor Green
|
Write-Host "`n===== Results =====" -ForegroundColor Green
|
||||||
@@ -201,7 +226,7 @@ try {
|
|||||||
Write-Host ""
|
Write-Host ""
|
||||||
|
|
||||||
# Display summary table
|
# Display summary table
|
||||||
$Results | Format-Table Domain, Username, Computer, LogonTime, LogonType -AutoSize
|
$Results | Format-Table Domain, Username, DisplayName, Computer, LogonTime, LogonType -AutoSize
|
||||||
|
|
||||||
} catch [System.Exception] {
|
} catch [System.Exception] {
|
||||||
if ($_.Exception.Message -match "No events were found") {
|
if ($_.Exception.Message -match "No events were found") {
|
||||||
|
|||||||
Reference in New Issue
Block a user