Tuesday, October 24, 2017

Disable/Delete Inactive AD Users

Export to CSV file of Inactive users of over 90 days

Dsquery user "OU=Faculty Staff, OU=All Users,DC=SSIS,DC=EDU,DC=VN" –inactive 90  > inactiveUsers.csv

alternately

Locate Inactive Accounts 

Use Powershell run as Administrator
To find users that have not logged into the system and have not reset password for the last 90 days:
$90Days = (get-date).adddays(-90)
Get-ADUser -SearchBase "OU=Faculty Staff, OU=All Users,DC=SSIS,DC=EDU,DC=VN" -filter {(lastlogondate -notlike "*" -OR lastlogondate -le $90days) -AND (passwordlastset -le $90days) -AND (enabled -eq $True)} -Properties lastlogondate, passwordlastset | Select-Object name, lastlogondate, passwordlastset| export-csv inactiveUsers.csv –notypeinformation

Disable the Inactive Accounts

This will update the description [with a date to help determine the deleted date] and disable the account with using the PassThru switch:

Get-ADUser -SearchBase "OU=Faculty Staff, OU=All Users,DC=SSIS,DC=EDU,DC=VN" -filter {lastlogondate -le $90days -AND passwordlastset -le $90days} -Properties lastlogondate, passwordlastset | set-aduser -Description ((get-date).toshortdatestring()) –passthru | Disable-ADAccount

Delete Inactive Accounts

Now that we have all the accounts disabled, we need to delete them. We can use the Remove-ADObject cmdlet to delete the account, and then use Get-ADUser to read the Description attribute. To compare the date that the account was disabled to the current date, we can use Where-Object, as shown here:

$14days = (get-date).adddays(-14)
Get-Aduser -SearchBase "OU=Faculty Staff, OU=All Users,DC=SSIS,DC=EDU,DC=VN" -Filter {enabled -eq $False} -properties description | Where { (get-date $_.Description) -le $14Days} | remove-adobject

The command sed will prompt for every user before deleting the accounts. To get a list, you can use WhatIf, or if you do not want to get prompted, you can use Confirm:$False, as shown here:

Get-Aduser -SearchBase "OU=Faculty Staff, OU=All Users,DC=SSIS,DC=EDU,DC=VN" -Filter {enabled -eq $False} -properties description | Where { (get-date $_.Description) -le $14Days} | remove-adobject –whatif

Get-Aduser -SearchBase "OU=Faculty Staff, OU=All Users,DC=SSIS,DC=EDU,DC=VN" -Filter {enabled -eq $False} -properties description | Where { (get-date $_.Description) -le $14Days} | remove-adobject –confirm:$False

All-in-One Script

#import the ActiveDirectory Module
Import-Module ActiveDirectory
#Create a variable for the date stamp in the log file
$LogDate = get-date -f yyyyMMddhhmm
#Sets the OU to do the base search for all user accounts, change for your env.
$SearchBase = "OU=Faculty Staff, OU=All Users,DC=SSIS,DC=EDU,DC=VN"
#Create an empty array for the log file
$LogArray = @()
#Sets the number of days to delete user accounts based on value in description field
$Disabledage = (get-date).adddays(-14)
#Sets the number of days to disable user accounts based on lastlogontimestamp and pwdlastset.
$PasswordAge = (Get-Date).adddays(-90)
#RegEx pattern to verify date format in user description field.
$RegEx = '^(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](20)\d\d$'
#Use ForEach to loop through all users with description date older than date set. Deletes the accounts and adds to log array.
ForEach ($DeletedUser in (Get-Aduser -searchbase $SearchBase -Filter {enabled -eq $False} -properties description ) ){
  #Verifies description field is in the correct date format by matching the regular expression from above to prevent errors with other disbaled users.
  If ($DeletedUser.Description -match $Regex){
    #Compares date in the description field to the DisabledAge set.
    If((get-date $DeletedUser.Description) -le $Disabledage){
      #Deletes the user object. This will prompt for each user. To suppress the prompt add "-confirm:$False". To log only add "-whatif".
      Remove-ADObject $DeletedUser
        #Create new object for logging
        $obj = New-Object PSObject
        $obj | Add-Member -MemberType NoteProperty -Name "Name" -Value $DeletedUser.name
        $obj | Add-Member -MemberType NoteProperty -Name "samAccountName" -Value $DeletedUser.samaccountname
        $obj | Add-Member -MemberType NoteProperty -Name "DistinguishedName" -Value $DeletedUser.DistinguishedName
        $obj | Add-Member -MemberType NoteProperty -Name "Status" -Value 'Deleted'
        #Adds object to the log array
        $LogArray += $obj
    }
  }
}
#Use ForEach to loop through all users with pwdlastset and lastlogontimestamp greater than date set. Also added users with no lastlogon date set. Disables the accounts and adds to log array.
ForEach ($DisabledUser in (Get-ADUser -searchbase $SearchBase -filter {((lastlogondate -notlike "*") -OR (lastlogondate -le $Passwordage)) -AND (passwordlastset -le $Passwordage) -AND (enabled -eq $True)} )) {
  #Sets the user objects description attribute to a date stamp. Example "11/13/2011"
  set-aduser $DisabledUser -Description ((get-date).toshortdatestring())
  #Disabled user object. To log only add "-whatif"
  Disable-ADAccount $DisabledUser
    #Create new object for logging
    $obj = New-Object PSObject
    $obj | Add-Member -MemberType NoteProperty -Name "Name" -Value $DisabledUser.name
    $obj | Add-Member -MemberType NoteProperty -Name "samAccountName" -Value $DisabledUser.samaccountname
    $obj | Add-Member -MemberType NoteProperty -Name "DistinguishedName" -Value $DisabledUser.DistinguishedName
    $obj | Add-Member -MemberType NoteProperty -Name "Status" -Value 'Disabled'
    #Adds object to the log array
    $LogArray += $obj
}
#Exports log array to CSV file in the temp directory with a date and time stamp in the file name.
$logArray | Export-Csv "C:\Temp\User_Report_$logDate.csv" -NoTypeInformation