Another short article with little context today.
The PowerShell script below will produce a report showing the Last Logon time of all enabled Active Directory users, it will also connect to Exchange On-Premise and request the last logon date of the mailbox. This can be useful to identify user accounts which are no longer in active use, even in organisations where mailboxes may have been retained once a user left.
There’s also a nifty status update built in that will tell you exactly how far the script has progressed and show an estimated time to completion.
The Script
# Locate all users that have not logged in within 12 months
$InactiveMonths = 12
$ExchangePowerShellEndpoint = "https://*Server*/PowerShell/"
$ExchangeAuthenticationModel = "Kerberos"
$UserCredential = Get-Credential -Message "Enter your credentials used to log into the Exchange Admin Portal"
$Months = (Get-Date).Addmonths(-($InactiveMonths))
$Users = Get-ADUser -Filter {LastLogonTimeStamp -lt $Months -and enabled -eq $true} -Properties LastLogonTimeStamp, mail |
select-object Name,@{Name="LastLogon"; Expression={[DateTime]::FromFileTime($_.lastLogonTimestamp).ToString('dd-MM-yyyy')}},SamAccountName,UserPrincipalName, mail
Write-Host "Located $($Users.count) users"
# Connect to Exchange
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $ExchangePowerShellEndpoint -Authentication $ExchangeAuthenticationModel -Credential $UserCredential
Import-PSSession $Session -DisableNameChecking -AllowClobber
# For each user, get the last mailbox login time
$currentIndex = 1
$startTime = Get-Date
foreach ($user in $users) {
# Estimate time to completion
$estimation = " "
$now = Get-Date
if ($currentIndex -gt 0) {
$elapsed = $now - $startTime # how much time has been spent
$average = $elapsed.TotalSeconds / $currentIndex # how many seconds per site
$totalSecondsToGo = ($users.Count - $currentIndex) * $average # seconds left
$span = New-TimeSpan -Seconds $totalSecondsToGo # time left
$estimatedCompletion = $now + $span # when it will be complete
$estimation = $estimatedCompletion.ToString() # readable estimation
}
# Show progress and estimated completion
Write-Progress -Id 0 -Activity "Retrieving Exchange Mailbox Stats" -Status "$currentIndex of $($Users.Count), Est Completion - $($estimation)" -PercentComplete (($currentIndex / $Users.Count) * 100)
# Get the mailboxes last logon time
try {
$mailboxStats = Get-MailboxStatistics -Identity $user.mail -ErrorAction Stop
$lastLogon = $mailboxStats.LastLogonTime
if($lastLogon -ne $null) {
$lastLogon = (Get-Date $lastLogon).ToShortDateString()
$user | Add-Member -Name 'mailboxLastAccess' -Type NoteProperty -Value $lastLogon
}
} catch {
$user | Add-Member -Name 'mailboxLastAccess' -Type NoteProperty -Value $null
}
$currentIndex++
}
Write-Progress -Id 0 -Activity " " -Status " " -Completed
# Export to CSV
$Users | export-csv C:\temp\LastLogOn_Users.csv -notypeinformation -noclobber