|
# Read the input parameters $Subtree and $NbDays
param([string] $Subtree = $(throw write-host `
"Please specify the DN of the container under which inactive accounts should be queried from." -Foregroundcolor Red),`
[string] $NbDays = $(throw write-host `
"Please specify the maximum number of days of inactivity allowed. Users who have not logged on for longer that the number of`
days specified will get disabled." -Foregroundcolor Red))
# Get the current date
$currentDate = [System.DateTime]::Now
# Convert the date to UTC format because all dates are expressed in UTC (GMT) format in Active Directory
$currentDateUtc = $currentDate.ToUniversalTime()
Write-Host "--------------------------------------------"
Write-Host " Disabling Inactive Accounts "
Write-Host " "$currentDate
Write-Host "--------------------------------------------"
Write-Host
# Initialize a hashtable where we are going to store the users' latest Lastlogon
$inactiveUserList = new-object System.Collections.HashTable
# Get the list of all the domain controllers for the current domain
$DCs = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().DomainControllers
foreach ($DC in $DCs)
{
# Set in the LDAP URL the DC hostname and the container DN specified on the command line
$LdapURL = "LDAP://" + $DC.Name + "/" + $Subtree
# Initialize a DirectorySearcher object
$searcher = New-Object System.DirectoryServices.DirectorySearcher([ADSI]$LdapURL)
# Set the attributes that you want to be returned from AD
$searcher.PropertiesToLoad.Add("distinguishedName") >$null
$searcher.PropertiesToLoad.Add("displayName") >$null
$searcher.PropertiesToLoad.Add("lastLogon") >$null
$searcher.PropertiesToLoad.Add("whenCreated") >$null
# Calculate the time stamp in Large Integer/Interval format using the $NbDays specified on the command line
$lastLogonTimeStampLimit = $currentDateUtc.AddDays(- $NbDays) # Get the date and time of $NbDays days ago
$lastLogonIntervalLimit = $lastLogonTimeStampLimit.ToFileTime()
# Construct the $creationDateStr in the format expected by the attribute whenCreated
$creationDate = $currentDateUtc.AddDays(- 1) # Get the date and time of 8 days ago
$YYYY = $creationDate.Year.ToString()
$MM = $creationDate.Month.ToString(); if ($MM.Length -eq 1) {$MM="0" + $MM};
$DD = $creationDate.Day.ToString(); if ($DD.Length -eq 1) {$DD="0" + $DD};
$hh = $creationDate.Hour.ToString(); if ($hh.Length -eq 1) {$hh="0" + $hh};
$min = $creationDate.Minute.ToString(); if ($min.Length -eq 1) {$min="0" + $min};
$ss = $creationDate.Second.ToString(); if ($ss.Length -eq 1) {$ss="0" + $ss};
$creationDateStr = $YYYY + $MM + $DD + $hh + $min + $ss + '.0Z'
Write-Host "Looking for all enabled users on ["$DC.Name"] whose account have been created before "$creationDate `
"("$creationDateStr")"
$searcher.Filter = "(&(objectCategory=person)(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(whenCreated<="`
+ $creationDateStr + "))"
#Setting the paging option to allow AD to bypass its default limit of 1000 objects returned per search request.
$searcher.PageSize = 100;
# Issue the LDAP Search request against AD
$users = $searcher.FindAll()
if ($users.Count -eq 0)
{
Write-Host " No account found on the DC ["$DC.Name"]"
}
else
{
Write-Host "["$users.Count"] accounts found on the DC ["$DC.Name"]"
}
foreach ($user in $users)
{
# Read the user properties
[string]$DN = $user.Properties.distinguishedname
[string]$displayName = $user.Properties.displayname
[string]$lastLogonInterval = $user.Properties.lastlogon
# Convert the date and time to the local time zone
$lastLogon = [System.DateTime]::FromFileTime($lastLogonInterval) # Time expressed in local time (and not GMT)
#Write-Host " The user "$displayName" ("$DN") last logged on to the DC ["$DC.Name"] on "$lastLogon #"("$lastLogonInterval")"
# If the hashtable does not already contain a record for the user add it. The key for the hashtable is the user DN
if (!($inactiveUserList.Keys -contains $DN))
{
$inactiveUserList[$DN] = $lastLogonInterval #The user logon time stamp is added to the list
}
elseif ($lastLogonInterval -gt $inactiveUserList[$DN])
{
#If the lastLogon value read is greater than the one previously recorded for the same user on another DC, then store in`
the hashtable the latest value
$inactiveUserList[$DN] = $lastLogonInterval #The list is updated with the latest logon time stamp for the user
}
}
Write-Host
}
if ($inactiveUserList.Count -gt 0)
{
Write-Host "Disabling ["$inactiveUserList.Count"] accounts that have not logged on since "$lastLogonTimeStampLimit "GMT `
("$lastLogonIntervalLimit")"
# For each user account recorded in the hashtable, disable the user account if its lastLogon is less than $lastLogonIntervalLimit `
(which is current-date - $NbDays)
foreach ($DN in $inactiveUserList.Keys)
{
if ($inactiveUserList[$DN] -lt $lastLogonIntervalLimit)
{
Write-Host "Disabling user: "$DN "[LastLogon:"$inactiveUserList[$DN]"]"
$ldapURL = "LDAP://" + $DN
$account= [ADSI]$ldapURL
$account.psbase.invokeset("AccountDisabled", "True")
$account.setinfo()
}
}
} |