Skip to content

Instantly share code, notes, and snippets.

@AfroThundr3007730
Last active March 14, 2021 21:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AfroThundr3007730/2a93cbe08ce06d5767bf1483b92ec7e4 to your computer and use it in GitHub Desktop.
Save AfroThundr3007730/2a93cbe08ce06d5767bf1483b92ec7e4 to your computer and use it in GitHub Desktop.
Script to disable inactive computer accounts after a set period and delete disabled accounts after another set period.
Start-Transcript C:\ProgramData\computer-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=Domain Controllers" -and
$_.DistinguishedName -notmatch "OU=VMWare" -and
$_.DistinguishedName -notmatch "OU=Linux"
} | 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)
$enabledComputers = accountFilter (Get-ADComputer -Filter { Enabled -eq $true } -Properties *)
$disabledComputers = accountFilter (Get-ADComputer -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 ($computer in $enabledComputers) {
# Disable any computer accounts not logged into since $inactive
$inactive = accountIsInactive $computer $inactiveDate
if ($inactive) {
Write-Host 'Disabling inactive computer account:' $computer.Name
Write-Host 'Last active timestamp:' $inactive
Disable-ADAccount -Identity $computer -Confirm:$false
}
}
foreach ($computer in $disabledComputers) {
# Delete any computer accounts disabled since $inactive (except servers)
$inactive = accountIsInactive $computer $disabledDate
if ($inactive -and $computer.DistinguishedName -notmatch 'OU=Managed Servers') {
Write-Host 'Deleting inactive computer account:' $computer.Name
Write-Host 'Last active timestamp:' $inactive
Remove-ADObject -Identity $computer -Recursive -Confirm:$false
}
}
Stop-Transcript
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment