Script for Disabling Inactive AD Accounts

Andrew L 21 Reputation points
2020-12-09T20:18:31.597+00:00

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 for business | Windows Client for IT Pros | Directory services | Active Directory
Windows for business | Windows Server | User experience | PowerShell
0 comments No comments
{count} votes

Accepted answer
  1. Rich Matheisen 47,901 Reputation points
    2020-12-09T20:42:36.247+00:00

    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!


2 additional answers

Sort by: Most helpful
  1. Vicky Wang 2,741 Reputation points
    2020-12-10T09:18:39.48+00:00

    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 person found this answer helpful.

  2. Thameur-BOURBITA 36,261 Reputation points Moderator
    2020-12-09T21:35:51.8+00:00

    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

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.