I had a request recently to provide an inactive user report for the past 60 days. Basically, find out which accounts have not logged in for the past 60 days so action can be taken against them.
The request was for a multi domain forest which queries every domain controller and gets the latest lastlogon value by comparing value from each. I wrote a script and wanted to share as other might find it handy too.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
<# .SYNOPSIS Get the last logon report of users that have not logged for the past XX (Default 60) days from multiple domain controllers. .DESCRIPTION Get details of users that have not logged on or are inactive for the past 60 days across the domain and get the latest value from multiple domain controllers .INPUTS None. Script captures Forest and Domain details when run in the environment. .OUTPUTS Generated output CSV file will be in the created in the same path from where the script was executed. .NOTES Version: 2.0 Author: Mohammed Wasay Email: [email protected] Web: www.mowasay.com Creation Date: 02/14/2020 .EXAMPLE Get-LastLogonReport.ps1 #> #Get Logged on user details $cuser = $env:USERDOMAIN + "\" + $env:USERNAME Write-Host -ForegroundColor Gray "Running script as: $cuser authenticated on $env:LOGONSERVER" #Get the Forest Domain $forest = (Get-ADForest).RootDomain #Get all the Domains in the Forest $domains = (Get-ADForest).Domains #Time format for report naming $timer = (Get-Date -Format MM-dd-yyyy) Write-Host -ForegroundColor Magenta "Your Forest is: $forest" #Loop through each domain foreach ($domain in $domains) { Write-Host -ForegroundColor Yellow "Working on Domain: $domain" #Get all the domain controllers in the domain $dcs = Get-ADDomainController -Filter * -Server $domain #Storing all the users in an array for comparison later $users = @() foreach ($dc in $dcs.Hostname) { Write-Host -ForegroundColor Cyan "Working on Domain Controller: $dc" #Days Inactive - Modify the value to the number of days (1,30,45,60,90,120) $DaysInactive = "60" $time = (Get-Date).Adddays( - ($DaysInactive)) #Get all AD Users with lastLogonTimestamp less than our time $users += Get-ADUser -Filter { lastlogondate -le $time } -Properties * -Server $dc | ` Select-Object Enabled, ` @{Name = "Domain"; Expression = { $domain } }, ` samAccountName, ` displayName, ` lastlogondate, ` lastlogon, ` @{Name = 'DC'; Expression = { $dc } }, ` whenCreated, ` description, ` distinguishedName, ` department, ` company, ` office } Write-Host -ForegroundColor Yellow "Sorting for most recent lastlogons" #Get the last logon from each server for every filtered user and used the last entry available $LatestLogOn = @() $users | Group-Object -Property samAccountName | ForEach-Object { $LatestLogOn += ($_.Group | Sort-Object -Property lastlogon -Descending)[0] $users.Clear() } #Export the results to a single file per forest/multidomain $LatestLogOn | Select-Object Enabled, ` Domain, ` samAccountName, ` displayName, ` @{Name = 'lastlogondatetime'; Expression = { [datetime]::FromFileTime($_.lastlogon) -replace '12/31/1600 7:00:00 PM', 'Never' -replace '1/1/1601 12:00:00 AM', 'Never' } }, ` lastlogon, ` DC, ` whenCreated, ` description, ` distinguishedName, ` department, ` company, ` office ` | Sort-Object lastlogondatetime -Descending | Export-Csv ./$forest-InactiveUserReport-$timer.csv -NoTypeInformation -Append #Uncomment below if exported results need to be multiple files seperated per domain #Export the results to a seperate file per domain <# $LatestLogOn | Select-Object Enabled, ` Domain, ` samAccountName, ` displayName, ` @{Name = 'lastlogondatetime'; Expression = { [datetime]::FromFileTime($_.lastlogon) -replace '12/31/1600 7:00:00 PM', 'Never' -replace '1/1/1601 12:00:00 AM', 'Never' } }, ` lastlogon, ` DC, ` whenCreated, ` description, ` distinguishedName, ` department, ` company, ` office ` | Sort-Object lastlogondatetime -Descending | Export-Csv ./$domain-InactiveUserReport-$timer.csv -NoTypeInformation -Append #> Write-Host -ForegroundColor Green "Report for $domain generated!" } Write-Host -ForegroundColor Green "------======= Done! =======------" |