Last active
June 29, 2020 04:05
-
-
Save Gunslap/223ada0870c3d5ce89c9 to your computer and use it in GitHub Desktop.
Scans Active Directory for inactive accounts and disables and relocates them accordingly.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.SYNOPSIS | |
This function disables accounts that are older than a certain threshhold. | |
.DESCRIPTION | |
Searches active directory for users based on an inputted searchbase for users that haven't logged in since a certain threshhold or haven't logged in ever and were created before that threshhold and disables them and marks in their description when and why they were disabled. | |
.PARAMETER $SearchBase | |
This is where to search in Active Directory. Must be in DN form: "ou=x,ou=x,dc=x,dc=x". | |
.PARAMETER NbDays | |
This is the number of days a user must be inactive for to require disabling | |
.PARAMETER LogFile | |
The location of the logfile. If a file is not present in that location, it will attempt to make it. | |
.PARAMETER emailTo | |
The email address to send general results to (never as thorough as logging) | |
.PARAMETER server | |
The AD Domain Controller to search from. | |
.EXAMPLE | |
FindAndDisable-Accounts -SearchBase "ou=Students,dc=Contoso,dc=com" -nbDays 100 -LogFile "\\Contososerver\scriptlogs$\DisabledStudentsLog.txt" -Verbose | |
This will search in the OU Students in the Contoso.com domain, that are inactive for 100 days, and verbosely log to the logfile specified. | |
#> | |
function FindAndDisable-Accounts | |
{ | |
[CmdLetBinding()] | |
Param( | |
[string]$SearchBase = "Nothing", | |
[string]$NbDays = 365, | |
[string]$LogFile, | |
[string]$emailTo = "[email protected]", | |
[string]$server = "domaincontroller" | |
) | |
#Create the Log File if it doesn't already exist | |
if (-not (Test-Path $LogFile)) | |
{ | |
New-Item $LogFile -ItemType file | |
} | |
#Get the current date | |
#Convert the local time to UTC format (because all dates are expressed in UTC [GMT] format in Active Directory) | |
$CurrentDate = (Get-Date).ToUniversalTime() | |
#Calculate the time stamp in Large Integer format using the $NbDays specified above | |
#LastLogonThreshhold holds the cutoff time for disabling | |
$LastLogonThreshhold = ($CurrentDate.AddDays(- $NbDays)).ToFileTimeUtc() | |
#Initialize the string for the body of the email report | |
#Write out the header information to the log file | |
$EmailBody = "Disabling Accounts Output`r`n" + $CurrentDate.Date + "`r`n*************************************`r`n" | |
$EmailBody >> $LogFile | |
$EmailBody += "For more information see the logfile at $LogFile" | |
#Get all users to work with | |
$Users = get-aduser -server $server -Filter * -SearchBase $SearchBase -Properties * | |
#Get all the properties that we need for those users | |
$Users = $Users | Select-Object -Property SamAccountName,Name,CN,DisplayName,lastLogonTimestamp,DistinguishedName,whenCreated,Enabled | |
foreach ($user in $Users) | |
{ | |
#initialize output and get the lastlogontimestamp for readability later | |
$Output = "" | |
$LastLogonTimeStamp = $user.lastLogonTimeStamp | |
#set the LastLogonTimeStamp to when the user was created if it is null. This occurs when the user hasn't logged in. | |
if($LastLogonTimeStamp -eq $null) | |
{ | |
$LastLogonTimeStamp = ($user.whenCreated).toFileTime() | |
} | |
#set readable values for printing of the lastLogonTimeStamp and Threshhold | |
#these are used in logging only, and 1600 years must be added to make them the proper year | |
$ReadableLastLogonTimeStamp = ([System.Datetime]$LastLogonTimeStamp).AddYears(1600) | |
$ReadableLastLogonThreshold = ([System.Datetime]$LastLogonThreshhold).AddYears(1600) | |
#Bypass any users that are disabled or are in the _Disabled OU | |
if (($user.Enabled -eq $false) -or ($user.DistinguishedName -match "OU=_DISABLED")) | |
{ | |
$Output = "Bypassing " + $user.DisplayName + " as it is already disabled." | |
#4>&1 pipes VERBOSE output into standard output, and >> pipes standard output to append to the specified destination | |
Write-Verbose $Output 4>&1 >> $LogFile | |
#$EmailBody += $Output | |
} | |
#if any of the name fields start with an underscore, that denotes an account we do not want changed | |
elseif ( ($user.Name -like "_*") -or ($user.CN -like "_*") -or ($user.DisplayName -like "_*") ) | |
{ | |
$Output = "Skipping " + $user.DisplayName + " (" + $user.SamAccountName + ") for one of it's names starting with an underscore." | |
Write-Verbose $Output 4>&1 >> $LogFile | |
#$EmailBody += $Output | |
} | |
#compare the lastlogontimestamp to the threshhold value (determined earlier by nbDays) | |
#in the case the user hasn't logged in, lastLogonTimeStamp will have been set to the date their account was created | |
elseif ($LastLogonTimeStamp -lt $lastLogonThreshhold) | |
{ | |
#at this point, it meets the criteria of being disabled | |
$Output = "Changing " + $user.DisplayName + " (" + $user.SamAccountName + "). Last Logon is " + $ReadableLastLogonTimeStamp + ". Threshhold is $ReadableLastLogonThreshold" | |
Write-Output $Output >> $LogFile | |
$EmailBody += $Output | |
Disable-Account -UserToDisable $user -LogFileLocation $LogFile -IsStudent $isStudent.IsPresent -friendlyDate $ReadableLastLogonTimeStamp | |
} | |
#this case does not meet the disabling criteria so there is no need to change it. | |
else | |
{ | |
$Output = "Not Changing " + $user.DisplayName + " (" + $user.SamAccountName + "). Last logon is " + $ReadableLastLogonTimeStamp + ". Threshhold is $ReadableLastLogonThreshold" | |
Write-Verbose $Output 4>&1 >> $LogFile | |
#Shouldn't need to email this part. | |
#$EmailBody += $Output | |
} | |
} | |
#Email list of changes made to the helpdesk: | |
$emailFrom = "[email protected]" | |
$subject = "Disabled Users Report for - $CurrentDate" | |
$smtpServer = "smtp.contoso.com" | |
$smtp = new-object Net.Mail.SmtpClient($smtpServer) | |
$smtp.Send($emailFrom, $emailTo, $subject, $Emailbody) | |
} | |
function Disable-Account | |
{ | |
param( | |
$UserToDisable, | |
$LogFileLocation, | |
$isStudent, | |
$friendlyDate | |
) | |
#get the current date | |
$CurrentDate = Get-Date | |
#get the user speicifed and set their account to disabled and their description to indicate the dates | |
Get-ADUser $UserToDisable.SamAccountName | Set-ADUser -Enabled $False -Description "DISABLED: $CurrentDate - LAST LOGON: $friendlyDate" #-WhatIf | |
#move their documents to the _old_user_accounts folder on their server | |
Move-Documents -UserToDisable $UserToDisable -LogFileLocation $LogFileLocation -isStudent $isStudent | |
} | |
function Move-Documents | |
{ | |
param( | |
$UserToDisable, | |
$LogFileLocation, | |
) | |
#get the nsid | |
$samAccountName = $UserToDisable.SamAccountName | |
$profile_folders = "\\$Server\ProfilesShare$" | |
$home_folders = "\\$Server\HomeShare$" | |
#make a hashtable of the folders needed | |
$array_folders = ($profile_folders,$home_folders) | |
foreach ($folder in $array_folders) | |
{ | |
Write-Host "Scanning $folder..." | |
#get the folder itself | |
$MainFolders = Get-ChildItem -Path $folder -Force | |
foreach ($SubFolder in $MainFolders) | |
{ | |
#if the account name matches the foldername and the folder isn't in the old_user_accounts folder already | |
if (($samAccountName | Select-String -Pattern $SubFolder) -and ($SubFolder -notlike "*_Old_user_accounts*")) | |
{ | |
#move and log the move | |
Write-Host "The user's folder: $SubFolder exists in: $folder" | |
$Output = "--> Moving the folder $folder\$SubFolder to _Old_user_accounts folder `r" | |
Write-Host $Output | |
Write-Output $Output >> $LogFileLocation | |
#Make sure the _Old_user_accounts folder exists: | |
if (-not (Test-Path $folder\_Old_user_accounts)) | |
{ | |
New-Item ("$folder\_Old_user_accounts") -type directory | |
} | |
Move-Item -Path $folder\$SubFolder $folder\_Old_user_accounts\$samAccountName\ -Force #-WhatIf | |
} | |
} | |
} | |
} | |
#Sample Run: | |
#FindAndDisable-Accounts -SearchBase "ou=Users,dc=contoso,dc=com" -nbDays 365 -LogFile "\\ContosoServer\e$\_Logs\DisabledUserssLog.txt" #-Verbose |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment