Files
ActiveDirectory/Get-InactiveUsers.ps1

144 lines
4.6 KiB
PowerShell

<#
.SYNOPSIS
Lists all Active Directory users who have not logged on for more than 90 days
(default) and are not disabled.
.DESCRIPTION
Uses Active Directory cmdlets to find all users and checks their last logon
date. Users who have had no active logon for longer than the configured
number of days (default 90) are returned.
.PARAMETER Days
Number of days after which a user is considered inactive. Defaults to 90.
.PARAMETER IncludeDisabled
If set, the script also includes DISABLED users in the results.
.PARAMETER SearchBase
If set, the script searches for users only within the specified OU(s). This
is an array, so multiple OUs can be supplied; each one is searched
recursively and the results are combined.
.EXAMPLE
.\Get-InactiveUsers.ps1
Displays users who have not been active for more than 90 days.
.EXAMPLE
.\Get-InactiveUsers.ps1 | Sort-Object LastLogonDate | Format-Table -AutoSize
Displays users who have not been active for more than 90 days, sorted by
last logon date.
.EXAMPLE
.\Get-InactiveUsers.ps1 -Days 180
Displays users who have not been active for more than 180 days.
.EXAMPLE
.\Get-InactiveUsers.ps1 -Days 365 -IncludeDisabled
Displays users who have not been active for more than 365 days, including
DISABLED users.
.EXAMPLE
.\Get-InactiveUsers.ps1 -SearchBase "OU=Users,DC=example,DC=com"
Displays users who have not been active for more than 90 days, searching
only within the specified OU.
.EXAMPLE
.\Get-InactiveUsers.ps1 | Export-Csv -Path .\Export_InactiveUsers.csv -NoTypeInformation -Encoding UTF8
Exports all inactive users in Active Directory to a CSV file.
.EXAMPLE
.\Get-InactiveUsers.ps1 | Set-ADUser -Enabled $false
Disables all inactive users in Active Directory.
.NOTES
Author: Petr Štěpán
Created: 2024-10-20
Version: 1.1.0
Changelog:
1.1.0 - Fixed -SearchBase to correctly support multiple OUs (Get-ADUser's
own -SearchBase only accepts one); added standard header,
Set-StrictMode/$ErrorActionPreference, error handling, exit codes.
1.0.0 - Initial version
#>
#Requires -Modules ActiveDirectory
[CmdletBinding()]
param (
[Parameter(Mandatory = $false, HelpMessage = 'Number of days after which a user is considered inactive.')]
[ValidateRange(15, [int]::MaxValue)]
[int]
$Days = 90,
[Parameter(Mandatory = $false, HelpMessage = 'Also include DISABLED users?')]
[switch]
$IncludeDisabled,
[Parameter(Mandatory = $false, HelpMessage = 'Search for users only within the specified OU(s).')]
[ValidateNotNullOrEmpty()]
[string[]]
$SearchBase
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
# Read-only script (queries Active Directory only) - no ShouldProcess needed.
# The caller decides what to do with the results (export, disable, ...) via the pipeline.
$propertiesToRetrieve = 'Name', 'SamAccountName', 'LastLogonDate', 'Enabled', 'PasswordNeverExpires', 'CanonicalName', 'DistinguishedName'
# Date beyond which a user is considered inactive
$inactiveDate = (Get-Date).AddDays(-$Days)
if ($IncludeDisabled) {
$parameters = @{
Filter = {
LastLogonDate -le $inactiveDate
}
}
}
else {
$parameters = @{
Filter = {
LastLogonDate -le $inactiveDate -and Enabled -eq $true
}
}
}
if ($SearchBase) {
# Get-ADUser's own -SearchBase only accepts a single OU, so each requested
# OU is queried separately and the results are combined.
$inactiveUsers = [System.Collections.Generic.List[object]]::new()
$failedOuCount = 0
foreach ($ou in $SearchBase) {
Write-Verbose "Searching for inactive users in OU '$ou'..."
try {
$ouUsers = Get-ADUser @parameters -SearchBase $ou -Properties $propertiesToRetrieve -ErrorAction Stop
foreach ($u in $ouUsers) { $inactiveUsers.Add($u) }
}
catch {
Write-Warning "Skipping OU '$ou': failed to query users - $_"
$failedOuCount++
}
}
if ($failedOuCount -eq $SearchBase.Count) {
Write-Error "Failed to retrieve users from any of the specified OUs."
exit 1
}
}
else {
Write-Verbose "Searching for inactive users across the entire domain..."
try {
$inactiveUsers = @(Get-ADUser @parameters -Properties $propertiesToRetrieve -ErrorAction Stop)
}
catch {
Write-Error "Failed to query inactive users from Active Directory: $_"
exit 1
}
}
$inactiveUsers | Select-Object -Property $propertiesToRetrieve
exit 0