Star InactiveStar InactiveStar InactiveStar InactiveStar Inactive

This script will query all enabled AD accounts, see which ones meet the criteria for inactive (defaults to 30 days). Use the "-Remediate" switch to disable and append the Info field in AD.

    Disables users based on criteria of switches

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

    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.

    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"

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

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

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


    Written by: Jeremy Corbello

    * Website:
    * Twitter:
    * LinkedIn:
    * Github:

    Change Log:
    V1.00 - 10/18/2017 - Initial version
    V1.01 - 10/18/2017 - Added exclusion support

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

        [Parameter( Mandatory=$false)]
        [string]$UpdateInformation = "Disabled due to inactivity",

        [Parameter( Mandatory=$false)]

        [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 {
        [Parameter( Position=0,Mandatory=$true)]
    "$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 += "`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