Skip to content

Instantly share code, notes, and snippets.

@AfroThundr3007730
Last active March 14, 2021 21:12
Show Gist options
  • Save AfroThundr3007730/d55c55bdeff05a1d5a2927e159ccb910 to your computer and use it in GitHub Desktop.
Save AfroThundr3007730/d55c55bdeff05a1d5a2927e159ccb910 to your computer and use it in GitHub Desktop.
Script to disable inactive user accounts after a set period and delete disabled accounts after another set period.
Start-Transcript C:\ProgramData\account-hygiene.log -Append
function accountFilter($accountList) {
# Filter out system principals and exempt accounts
return $accountList | Where-Object {
# Don't process these accounts
$_.DistinguishedName -notmatch "OU=Service Accounts" -and
$_.DistinguishedName -notmatch "OU=Admin Accounts" -and
$_.DistinguishedName -notmatch "OU=DA Accounts" -and
$_.DistinguishedName -notmatch "OU=Special" -and
# Builtin and system principals
$_.Name -notmatch "defaultaccount" -and
$_.Name -notmatch "instructor" -and
$_.Name -notmatch "krbtgt" -and
$_.Name -notmatch "guest" -and
$_.Name -notmatch "mail"
} | Sort-Object
}
$inactiveDays = 30 # Days before account gets disabled
$disabledDays = 30 # Days before account gets deleted
$inactiveDate = (Get-Date).AddDays(-$inactiveDays)
$disabledDate = $inactiveDate.addDays(-$disabledDays)
$enabledUsers = accountFilter (Get-ADUser -Filter { Enabled -eq $true } -Properties *)
$disabledUsers = accountFilter (Get-ADUser -Filter { Enabled -eq $false } -Properties *)
$domainControllers = Get-ADDomainController -Filter *
if ($domainControllers.Count -lt 1) { Write-Host 'No domain controllers!'; exit }
function getLastLogon($account) {
$lastLogon = $null
# Have to check each DC because the value doesn't sync
foreach ($dc in $domainControllers) {
$logon = (Get-ADObject -Identity $account -Server $dc -Properties lastLogon).lastLogon
# Use the latest of the values
if ($logon -gt $lastLogon) { $lastLogon = $logon }
}
if ($lastLogon) {
# Dates are a delta since Jan 01, 1600, so add 1600 years
return ([datetime][Math]::Max([Int64]0, $lastLogon)).AddYears(1600)
}
}
function accountIsInactive($account, $threshold) {
$lastLogonDate = getLastLogon $account
# Return true if lastLogon is before threshold or if user
# never logged in and account created before threshold
if ($lastLogonDate -and $lastLogonDate -lt $threshold) {
return $lastLogonDate
}
elseif (!($lastLogonDate) -and $account.WhenCreated -lt $threshold) {
return $account.WhenCreated
}
return $False
}
Write-Host 'The {0} day inactive account cutoff date is: {1}' -f $inactiveDays, $inactiveDate
Write-Host 'The {0} day disabled account cutoff date is: {1}' -f $disabledDays, $disabledDate
foreach ($user in $enabledUsers) {
# Disable any user accounts not logged into since $inactiveDate
$inactive = accountIsInactive $user $inactiveDate
if ($inactive) {
Write-Host 'Disabling inactive user account:' $user.Name
Write-Host 'Last active timestamp:' $inactive
Disable-ADAccount -Identity $user -Confirm:$false
}
}
foreach ($user in $disabledUsers) {
# Delete any user accounts disabled since $disabledDate (except instructors)
$inactive = accountIsInactive $user $disabledDate
if ($inactive -and $user.DistinguishedName -notmatch 'OU=Instructors') {
Write-Host 'Deleting inactive user account:' $user.Name
Write-Host 'Last active timestamp:' $inactive
Remove-ADUser -Identity $user -Confirm:$false
}
}
Stop-Transcript
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment