question

AndrewL-7436 avatar image
0 Votes"
AndrewL-7436 asked HainesRoger-1110 commented

Script for Disabling Inactive AD Accounts

Hello everyone,

I'm looking for a powershell script to disable inactive AD user accounts (past 90 days), which will also exclude our domain service accounts.

Can someone point me in the right direction?

Thanks in advance!



windows-server-powershellwindows-active-directory
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

RichMatheisen-8856 avatar image
0 Votes"
RichMatheisen-8856 answered RichMatheisen-8856 commented

Is it safe to assume that "inactive" means not having logged on in the domain?

 Search-ADAccount -AccountInactive -TimeSpan -90:00:00:00 | Disable-ADAccount

Before you use that bit of code, you might want to add "-WhatIf" to the Disable-AdAccount before you run it!

· 4
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hello Rich.

Thank you for your response. And yes, by inactive I meant someone who has not logged into AD.

The second part of my question is, how would I exclude our service accounts from the list of accounts to disable?

Thanks again!

0 Votes 0 ·

Adding the -UserOnly switch to Search-AdAccount will eliminate accounts that are not users. But "service accounts" are users! How do you distinguish between a "service" account and a normal "user" account in your organization? Are they named differently? Are the in a separate OU? Do they have a property populated with a value that normal users don't have? Are service accounts all members of a security group (or several security groups) that normal users are not members of?

0 Votes 0 ·

Unfortunately, here is currently nothing distinguishing our service accounts from a 'normal' user.

As you pointed out, there needs to be. So...I will move them into their own OU.

With that said, how do I exclude/include an OU to disable inactive user accounts?

0 Votes 0 ·
Show more comments
Thameur-BOURBITA avatar image
0 Votes"
Thameur-BOURBITA answered

Hi,

You can use the script mentioned on this link :

Disable-inactive-users-and-766a9a1c




Please don't forget to mark this reply as answer if it help you to fix your issue

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

VickyWang-MFST avatar image
0 Votes"
VickyWang-MFST answered HainesRoger-1110 commented

This script will disable AD users based on the LastLogonDate field in AD and update the Info field in AD as well for each user.

Data is output to a central log file.

Must have the ActiveDirectory module installed. Script will import the module itself.

Default values are as follows:

User must have not logged in for 30 days
Info field in AD will be appended with "Disabled due to inactivity - <DATE>"
Log name defaults to "LogFile.txt" in the invokation directory




PowerShell
<#
.SYNOPSIS
Disable-InactiveUsers.ps1
Disables users based on criteria of switches


.DESCRIPTION
Disables users based on criteria of switches. Switches are not mandatory as base values have been input.


.PARAMETER TimeFrame
Number of days inactive that an account must be to be disabled
Default value is 30 days.


.PARAMETER UpdateInformation
String value that will be appended to the end of the "Info" field in Active Directory.
Default value is "Disabled due to inactivity" with the date appended to the end.


.PARAMETER Remediate
Switch will disable the AD accounts and append the Info fields.


.PARAMTER LogName
String value for the name of the log file.
Default value is "LogFile.txt"


.PARAMETER ExclusionsPath
Location of an Exclusions list. Input the path to a text file with 1 sAMAccountName per line if the account should not be disabled.
You can run this script without the Remediate parameter, then check the "triggered.csv" file to see what would have been disabled.
Populate your txt file with data from the "triggered.csv" file.


.PARAMETER TriggeredPath
Name for a CSV of accounts that satisfy the inactive account parameters.
Defaults to "triggered.csv"


.EXAMPLE
.\Disable-InactiveUsers.ps1 -TimeFrame 90 -Remediate


.EXAMPLE
.\Disable-InactiveUsers.ps1 -LogName some_other_log.txt


.EXAMPLE
.\Disable-InactiveUsers.ps1 -ExclusionsPath exclusions.txt -Remediate


.LINK
https://www.jeremycorbello.com


.NOTES
Written by: Jeremy Corbello


 * Website:    https://www.jeremycorbello.com 
 * Twitter:    https://twitter.com/JeremyCorbello 
 * LinkedIn:    https://www.linkedin.com/in/jacorbello/ 
 * Github:    https://github.com/jacorbello 
 
 Change Log: 
 V1.00 - 10/18/2017 - Initial version 
 V1.01 - 10/18/2017 - Added exclusion support 

>


[CmdletBinding()]
param (
[Parameter( Mandatory=$false)]
[int]$TimeFrame = 30,


     [Parameter( Mandatory=$false)] 
     [string]$UpdateInformation = "Disabled due to inactivity", 
 
     [Parameter( Mandatory=$false)] 
     [switch]$Remediate, 
 
     [Parameter( Mandatory=$false)] 
     [string]$LogName = "LogFile.txt", 
 
     [Parameter( Mandatory=$false)] 
     [string]$ExclusionsPath = $null, 
 
     [Parameter( Mandatory=$false)] 
     [string]$TriggeredPath = ".\triggered.csv" 
 ) 

$Date = Get-Date -Format "MM/dd/yyyy"
$LogDate = Get-Date -Format "yyyy MMM d - HH:mm:ss tt"
$myDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$LogPath = "$myDir\$LogName"
$TriggeredPath = "$myDir\$TriggeredPath"
$Report = New-Object PSObject
$TriggeredUsers = @()
$Exclusions = Get-Content $ExclusionsPath


Import-Module ActiveDirectory


$Users = Get-ADUser -Properties LastLogonDate,SamAccountName -Filter {Enabled -eq $true}


Function Write-LogFile {
[CmdletBinding()]
param(
[Parameter( Position=0,Mandatory=$true)]
[string]$LogData
)
"$Date - $LogData" | Out-file -FilePath $LogPath -Append
}


foreach ($User in $Users) {
if ($Exclusions -notcontains $User.SamAccountName) {
if ($User.LastLogonDate -lt (Get-Date).AddDays(-$TimeFrame) -AND $User.LastLogonDate -ne $null) {
if ($Remediate) {
if ($UpdateInformation -ne $null) {
$Info = Get-ADUser $User.DistinguishedName -Properties info | Where-Object {$.info}
$Info += "`n $UpdateInformation - $Date"
try {
Set-ADUser -Replace @{info="$Info"} -ErrorAction Stop
Write-LogFile -LogData "Successfully set Info field for $($User.Name). New Info: $Info"
}
catch {
Write-LogFile -LogData "Error - Failed to set Info field for $($User.Name) - $
"
}
}
try {
Disable-ADAccount -Identity $User.DistinguishedName -ErrorAction Stop
Write-LogFile -LogData "$($User.Name) successfully disabled"
}
catch {
Write-LogFile -LogData "Error - Failed to disable AD Account $($User.Name) - $_"
}
}
$TriggeredUsers += $User | Select Name,LastLogonDate,SamAccountName
}
}
}


$TriggeredUsers | Format-Table
$TriggeredUsers | Export-Csv $TriggeredPath -NoTypeInformation

· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi Vicky, Thank you for this answer, which I think, may be what I'm looking for. However, the format seems to be out of whack? Is there a link where I can download or copy this script?

0 Votes 0 ·