I have a command that will export a list of users who have logged in for 12 months but I am struggling to export the last login date and time.
The command is as follows:
Search-ADAccount –AccountInActive -UsersOnly –TimeSpan 365:00:00:00 –ResultPageSize 2000 –ResultSetSize $null |?{$_.Enabled –eq $True} | Select-Object Name, SamAccountName, DistinguishedName, lastLogon| Export-CSV “C:\Users\Me\Desktop\InactiveUsers.CSV” –NoTypeInformation
But lastLogon is showing a blank in the CSV file.
I am new to PowerShell I understand the command can be made much smoother.
Any help on this is much appreciated.
Search-ADAccount
doesn't have an option to pull other attributes from the AD Objects than the default ones, you can use Get-ADUser
with an elaborate filter to query the users who haven't logged on for the past year. One option is to query the user's lastLogonTimeStamp
attribute however by doing so you're risking not getting accurate results because this attribute is not replicated in real time. To get accurate results one must query the user's lastLogon
attribute but, since this attribute is not replicated across the Domain, one must query all Domain Controllers to get the latest logon from the user.
For more information on this topic, please check this excellent TechNet Article: Understanding the AD Account attributes - LastLogon, LastLogonTimeStamp and LastLogonDate.
$dateLimit = [datetime]::UtcNow.AddYears(-1).ToFileTimeUtc()
$AllDCs = Get-ADDomainController -Filter *
$logons = @{}
# NOTE:
# - Use `!` for Enabled objects only: "(!userAccountControl:1.2.840.113556.1.4.803:=2)"
# or remove the clause to find both, Enabled and Disabled users.
# - The "(lastLogon<=$dateLimit)" clause can be removed to find all users latest login.
$params = @{
LDAPFilter = -join @(
'(&' # AND, all conditions must be met
'(!samAccountName=krbtgt)' # exclude krbtgt from this query
'(!samAccountName=Guest)' # exclude Guest from this query
'(userAccountControl:1.2.840.113556.1.4.803:=2)' # Disabled objects only
"(lastLogon<=$dateLimit)" # lastLogon is below the limit
')' # close AND clause
)
Properties = 'lastLogon'
# Add `SearchBase = "OUPath"` here if targeting a specific OU
}
foreach ($DC in $AllDCs) {
$params['Server'] = $DC
foreach ($user in Get-ADUser @params) {
# this condition is always met on first loop iteration due to ldap filtering condition
if ($logons[$user.samAccountName].LastLogon -lt $user.LastLogon) {
$logons[$user.samAccountName] = $user
}
}
}
$logons.Values | ForEach-Object {
[PSCustomObject]@{
Name = $_.Name
SamAccountName = $_.SamAccountName
DistinguishedName = $_.DistinguishedName
lastLogon = [datetime]::FromFileTimeUtc($_.lastLogon).ToString('u')
}
} | Export-Csv 'C:\Users\Me\Desktop\InactiveUsers.CSV' -NoTypeInformation