All expired user accounts and the accounts that are about to expire

image_pdfimage_print

A colleague of mine asked me to write a script with the Active Directory users with an account about to expire. So I created this script for him:

Account with an expiry date.

Account with an expiry date.


1
2
3
4
5
6
7
8
$arrUsers = @()
$arrOU    = @("OU=Users,OU=OU1,DC=testdomain,DC=local,DC=lan","OU=Users,OU=OU2,DC=testdomain,DC=local,DC=lan")
 
ForEach($objOU in $arrOU)
 {
  $arrUsers += (Search-ADAccount -AccountExpiring -SearchBase $objOU -UsersOnly) | Select-Object "AccountExpirationDate","Name",@{Name="OU";Expression={($_."DistinguishedName" -split "=",3)[-1]}},"Enabled","LastLogonDate","LockedOut","ObjectClass","PasswordExpired","PasswordNeverExpires","SamAccountName","UserPrincipalName"
 }
$arrUsers | Sort-Object -Property "OU","Name" | Export-Csv "c:\temp\usersabouttoexpire.csv" -NoTypeInformation

It does what it should do, but not flexible. It can be used in one situation but needs modification for other situations. Also, you cannot specify the number of days when the account is about to expire.

So I created the script AccountsAboutToExpire (v10).ps1.

There are some parameters:

  • OUs: Specify the OUs, seperated by a comma.
  • IncludeChildOUs: Use this switch to include the child OU’s.
  • NumberOfDaysToExpirationDate: Specify the number of days in which the account expires. Default = 7

This script does not only give the accounts that are about to expire, but also the expired user accounts.

A demonstration of this script can be found on my YouTube channel: the script and AppV Repository or view it below:

The script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
<#
.SYNOPSIS
    Gives the accounts that about to expire within the given period.
 
.DESCRIPTION
    This script gives the accounts that are about to expire within the given period in a CSV file.
 
.EXAMPLE
    Reports all the accounts that are about to expire in the OUs OU=Users,OU=OU1,DC=testdomain,DC=local,DC=lan and OU=Users,OU=OU2,DC=testdomain,DC=local,DC=lan
    ."\AccountsAboutToExpire V10).ps1" -OUs "OU=Users,OU=OU1,DC=testdomain,DC=local,DC=lan","OU=Users,OU=OU2,DC=testdomain,DC=local,DC=lan"
 
.EXAMPLE
    Reports all the accounts that are about to expire in the OU DC=testdomain,DC=local,DC=lan, including the child OU's
    ."\AccountsAboutToExpire V10).ps1" -OUs "DC=testdomain,DC=local,DC=lan" -IncludeChildOUs
 
.EXAMPLE
    Reports all the accounts that are about to expire witin 60 days in the OU DC=testdomain,DC=local,DC=lan, including the child OU's
    ."\AccountsAboutToExpire V10).ps1" -OUs "DC=testdomain,DC=local,DC=lan" -IncludeChildOUs -NumberOfDaysToExpirationDate 60
 
.NOTES
    Author:  Willem-Jan Vroom
    Website: 
    Twitter: @TheStingPilot
 
v0.1:
   * Initial version. 
 
v1.0:
   * Included:
      - All the expired user accounts
      - Sort on expiration date. 
#>
 
[CmdLetBinding()]
 
param
(
# Specify the OUs, seperated by a comma. 
[Parameter(Mandatory=$True)]
[string[]] $OUs,
 
# Use this switch to include the child OU's. 
[Parameter(Mandatory=$False)]
[switch]  $IncludeChildOUs,
 
# Specify the number of days in which the account expires. Default = 7
[Parameter(Mandatory=$False)]
[string]  $NumberOfDaysToExpirationDate=7
)
 
# =============================================================================================================================================
# Function block
# =============================================================================================================================================
 
  Function Get-AccountsAboutToExpire
   {
 
    param
     (
      [string] $OU,
      [Switch] $InclChildOUs,
      [string] $NumDays
     )
 
    $arrItems       = @()
    $arrAboutToExp  = New-Object PSObject
    $arrExpired     = New-Object PSObject
    $strSearchScope = "OneLevel"
 
    if($InclChildOUs)
     {
      $strSearchScope = "SubTree"
     } 
 
    Try
     {
      $arrAboutToExp  = (Search-ADAccount -AccountExpiring -SearchBase $objOU -UsersOnly -SearchScope $strSearchScope -TimeSpan $NumDays) | Select-Object "AccountExpirationDate","Name",@{Name="OU";Expression={($_."DistinguishedName" -split "=",3)[-1]}},@{Name="ExpiredAccount";Expression={$False}},"Enabled","LastLogonDate","LockedOut","PasswordExpired","PasswordNeverExpires"
      $arrExpired     = (Search-ADAccount -AccountExpired  -SearchBase $objOU -UsersOnly -SearchScope $strSearchScope)                    | Select-Object "AccountExpirationDate","Name",@{Name="OU";Expression={($_."DistinguishedName" -split "=",3)[-1]}},@{Name="ExpiredAccount";Expression={$True}}, "Enabled","LastLogonDate","LockedOut","PasswordExpired","PasswordNeverExpires" 
      $arrItems      += $arrAboutToExp
      $arrItems      += $arrExpired
     }
      Catch
     {
      Write-Warning "The OU $OU has not been found."
     }
 
    Return $arrItems
 
   }
 
Function Check-HasAdminRights
 {
 
  <#
  .NOTES
  ========================================================================================================================
  Created with:     Windows PowerShell ISE
  Created on:       11-January-2019
  Created by:       Willem-Jan Vroom
  Organization:     
  Functionname:     Check-HasAdminRights
  ========================================================================================================================
  .SYNOPSIS
 
  This function checks if an user has admin rights. The function returns $true or $false
 
  #>
 
  If (([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
   {
    Return $True
   }
    else
   {
    Return $False
   }
 }
 
# =============================================================================================================================================
# End function block
# =============================================================================================================================================
 
# ========================================================================================================================
# Stop the script for a non admin user
# ========================================================================================================================
 
  if(-not(Check-HasAdminRights))
  {
   Write-Error "The current user has no admin rights. Please rerun the script with elevated rights." -Category PermissionDenied
   Exit 999
  }
 
# =============================================================================================================================================
# Check if the module ActiveDirectory has been loaded.
# =============================================================================================================================================
 
  if(-not(Get-Module -ListAvailable ActiveDirectory))
   {
    Write-Warning "The module ActiveDirectory is not found. Thus quitting."
    Exit 9
   }
 
# =============================================================================================================================================
# Define the variables
# =============================================================================================================================================
 
  $arrUsers      = @()
  $strCurrentDir = Split-Path -parent $MyInvocation.MyCommand.Definition
 
# =============================================================================================================================================
# Define the output file
# =============================================================================================================================================
 
  $strOutputFile = "UserAccounts About to Expire (" + (Get-Date).ToString('G') + ").csv"
  $strOutputFile = $strOutputFile.replace(":","-").Replace("/","-")
  $strOutputFile = $strCurrentDir + "\" + $strOutputFile  
 
# =============================================================================================================================================
# Process the OUs.
# =============================================================================================================================================
 
  ForEach($objOU in $OUs)
   {
    if($IncludeChildOUs)
     {
      $arrUsers += Get-AccountsAboutToExpire -OU $objOU -NumDays $NumberOfDaysToExpirationDate -InclChildOUs
     }
      else
     {
      $arrUsers += Get-AccountsAboutToExpire -OU $objOU -NumDays $NumberOfDaysToExpirationDate
     }
   }
 
# =============================================================================================================================================
# Write the output to a csv file.
# =============================================================================================================================================
 
  $arrUsers | Sort-Object -Property "AccountExpirationDate","OU","Name" | Export-Csv $strOutputFile -NoTypeInformation
Get default help.

Get default help.

 

Get detailed help.

Get detailed help.

 

Output in Excel.

Output in Excel.

 

Current version: AccountsAboutToExpire (v10)

Previous versions:

Permanent link to this article: https://www.vroom.cc/wordpress/overview-of-all-user-accounts-that-are-about-to-expire/