SHOW:
|
|
- or go back to the newest paste.
1 | ########################################################### | |
2 | # | |
3 | # AUTHOR : PowerMonkey500 | |
4 | # | |
5 | # WARNING: THIS SCRIPT WILL OVERWRITE EXTENSIONATTRIBUTE3, MAKE SURE YOU ARE NOT USING IT FOR ANYTHING ELSE | |
6 | # | |
7 | # Make sure you create the OU structure as detailed in the "declarations" section. This script will not create the OUs for you. | |
8 | # | |
9 | ########################################################### | |
10 | ||
11 | #LOGGING FUNCTION - starts transcript and cleans logs older than specified retention date. | |
12 | Function Start-Logging{ | |
13 | param ( | |
14 | [Parameter(Mandatory=$true)][String]$LogDirectory, | |
15 | [Parameter(Mandatory=$true)][String]$LogName, | |
16 | [Parameter(Mandatory=$true)][Int]$LogRetentionDays | |
17 | ) | |
18 | ||
19 | #Sets screen buffer from 120 width to 500 width. This stops truncation in the log. | |
20 | $ErrorActionPreference = 'SilentlyContinue' | |
21 | $pshost = get-host | |
22 | $pswindow = $pshost.ui.rawui | |
23 | ||
24 | $newsize = $pswindow.buffersize | |
25 | $newsize.height = 3000 | |
26 | $newsize.width = 500 | |
27 | $pswindow.buffersize = $newsize | |
28 | ||
29 | $newsize = $pswindow.windowsize | |
30 | $newsize.height = 50 | |
31 | $newsize.width = 500 | |
32 | $pswindow.windowsize = $newsize | |
33 | $ErrorActionPreference = 'Continue' | |
34 | ||
35 | #Create log directory if it does not exist already | |
36 | If (!(Test-Path $LogDirectory)){mkdir $LogDirectory} | |
37 | ||
38 | #Starts logging. | |
39 | New-Item -ItemType directory -Path $LogDirectory -Force | Out-Null | |
40 | $Today = Get-Date -Format M-d-y | |
41 | Start-Transcript -Append -Path ($LogDirectory + "\" + $LogName + "." + $Today + ".log") | Out-Null | |
42 | ||
43 | #Shows proper date in log. | |
44 | Write-Output ("Start time: " + (Get-Date)) | |
45 | ||
46 | #Purges log files older than X days | |
47 | $RetentionDate = (Get-Date).AddDays(-$LogRetentionDays) | |
48 | Get-ChildItem -Path $LogDirectory -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $RetentionDate } | Remove-Item -Force | |
49 | } | |
50 | ||
51 | #DECLARATIONS | |
52 | #Declares misc variables. | |
53 | $LogDirectory = "C:\Logs\Disable-InactiveADAccountsLog" #No trailing slash | |
54 | $LogName = "Disable-InactiveADAccountsLog" | |
55 | $MovedUsers = 0 #Leave at 0. | |
56 | $MovedComputers = 0 #Leave at 0. | |
57 | ||
58 | $ParentOU = "OU=Disabled Objects,DC=domain,DC=local" | |
59 | ||
60 | #CREATE AN OU STRUCTURE UNDER YOUR PARENT OU AS FOLLOWS: | |
61 | # | |
62 | # Parent OU (specified above) | |
63 | # -> Users | |
64 | # --> 0-30 Days | |
65 | # --> 30-180 Days | |
66 | # --> Over 180 Days | |
67 | # | |
68 | # -> Computers | |
69 | # --> 0-30 Days | |
70 | # --> 30-180 Days | |
71 | # --> Over 180 Days | |
72 | ||
73 | #START LOGGING | |
74 | Start-Logging -logdirectory $LogDirectory -logname $LogName -LogRetentionDays 30 | |
75 | ||
76 | #MOVE NEWLY DISABLED USERS | |
77 | Write-Host "" | |
78 | Write-Output "NEWLY DISABLED MOVE:" | |
79 | #Gets all newly users. msExchRecipientTypeDetails makes sure we are excluding things like shared mailboxes. | |
80 | Write-Output "Getting newly disabled users..." | |
81 | $DisabledUsers = Search-ADAccount -AccountDisabled -UsersOnly | Get-ADUser -Properties msExchRecipientTypeDetails,info,Enabled,distinguishedName,ExtensionAttribute3 | Where {@(1,128,65536,2097152,2147483648,$null) -contains $_.msExchRecipientTypeDetails -and $_.DistinguishedName -notlike "*Builtin*"} | |
82 | ||
83 | Write-Output ($DisabledUsers.Count.toString() + " newly disabled user objects were found.") | |
84 | ||
85 | #Loops through the newly disabled users found. | |
86 | ForEach ($DisabledUser in $DisabledUsers){ | |
87 | #Moves the user. | |
88 | Write-Output ("Moving user: " + $DisabledUser.SamAccountName + "...") | |
89 | Move-ADObject -Identity $DisabledUser.DistinguishedName -TargetPath "OU=0-30 Days,OU=Users,$ParentOU" | |
90 | $MovedUsers++ | |
91 | ||
92 | #Sets the info (notes) field with the old OU. | |
93 | #Formats the new info field (notes). Retains old info if any exists. | |
94 | Write-Output ("Setting info field for user: " + $DisabledUser.SamAccountName + "...") | |
95 | #Gets the parent OU. | |
96 | $OU = $DisabledUser.DistinguishedName.Split(',',2)[1] | |
97 | If ($DisabledUser.Info -eq $null -or $DisabledUser.Info -eq ""){$NewInfo = "OLD OU: " + $OU} | |
98 | Else{$NewInfo = "OLD OU: " + $OU + "`n" + $DisabledUser.Info} | |
99 | Set-ADUser -Identity $DisabledUser.SamAccountName -Replace @{info=$NewInfo} | |
100 | ||
101 | #Sets ExtensionAttribute3 for the date of disablement if not already set. | |
102 | If ($DisabledUser.ExtensionAttribute3 -notlike "*DISABLED*" -and $DisabledUser.ExtensionAttribute3 -notlike "*INACTIVE*"){ | |
103 | $Date = "DISABLED ON " + (Get-Date) | |
104 | Write-Output ("Setting ExtensionAttribute3 for user: " + $DisabledUser.SamAccountName + "...") | |
105 | Set-ADUser -Identity $DisabledUser.SamAccountName -Replace @{ExtensionAttribute3=$Date} | |
106 | } | |
107 | } | |
108 | ||
109 | #MOVE NEWLY DISABLED COMPUTERS | |
110 | #Get disabled computer accounts. | |
111 | Write-Output "Getting disabled computers..." | |
112 | $DisabledComputers = Get-ADComputer -Filter * -Properties Enabled,Description,distinguishedName,ExtensionAttribute3 | Where {` | |
113 | $_.Enabled -eq $False -and ` | |
114 | $_.DistinguishedName -notlike "*$ParentOU" | |
115 | } | |
116 | ||
117 | Write-Output ($DisabledComputers.Count.toString() + " newly disabled computer objects were found.") | |
118 | ||
119 | ForEach ($DisabledComputer in $DisabledComputers){ | |
120 | #Moves the Computer. | |
121 | Write-Output ("Moving computer: " + $DisabledComputer.SamAccountName + "...") | |
122 | Move-ADObject -Identity $DisabledComputer.DistinguishedName -TargetPath "OU=0-30 Days,OU=Computers,$ParentOU" | |
123 | $MovedComputers++ | |
124 | ||
125 | #Sets the description (notes) field with the old OU. | |
126 | #Formats the new description field (notes). Retains old Description if any exists. | |
127 | Write-Output ("Setting Description field for computer: " + $DisabledComputer.SamAccountName + "...") | |
128 | #Gets the parent OU. | |
129 | $OU = $DisabledComputer.DistinguishedName.Split(',',2)[1] | |
130 | If ($DisabledComputer.Description -eq $null -or $DisabledComputer.Description -eq ""){$NewDescription = "OLD OU: " + $OU} | |
131 | Else{$NewDescription = "OLD OU: " + $OU + " | " + $DisabledComputer.Description} | |
132 | Set-ADComputer -Identity $DisabledComputer.SamAccountName -Replace @{Description=$NewDescription} | |
133 | ||
134 | #Sets ExtensionAttribute3 for the date of disablement if not already set. | |
135 | If ($DisabledComputer.ExtensionAttribute3 -notlike "*DISABLED*" -and $DisabledComputer.ExtensionAttribute3 -notlike "*INACTIVE*"){ | |
136 | $Date = "DISABLED ON " + (Get-Date) | |
137 | Write-Output ("Setting ExtensionAttribute3 for computer: " + $DisabledComputer.SamAccountName + "...") | |
138 | Set-ADComputer -Identity $DisabledComputer.SamAccountName -Replace @{ExtensionAttribute3=$Date} | |
139 | } | |
140 | } | |
141 | ||
142 | #INCREMENT THROUGH OUS BASED ON AGE | |
143 | Write-Host "" | |
144 | Write-Output "OU INCREMENTATION:" | |
145 | #Gets objects in the disabled OU | |
146 | $DisabledOUUsers = Get-ADUser -Filter * -SearchBase "$ParentOU" -Properties ExtensionAttribute3,DistinguishedName,SamAccountName | |
147 | $DisabledOUComputers = Get-ADComputer -Filter * -SearchBase "$ParentOU" -Properties ExtensionAttribute3,DistinguishedName,SamAccountName | |
148 | ||
149 | #USERS | |
150 | #Declares counts for output. | |
151 | $30to180DayMovedUsers = 0 | |
152 | $180DayMovedUsers = 0 | |
153 | ||
154 | #Loops through users and checks if older than 30 days. | |
155 | ForEach ($DisabledOUUser in $DisabledOUUsers){ | |
156 | #Sets the date disabled if not already set | |
157 | If ($DisabledOUUser.ExtensionAttribute3 -eq "" -or $DisabledOUUser.ExtensionAttribute3 -eq $null){ | |
158 | Write-Output ("Setting ExtensionAttribute 3 for user: " + $DisabledOUUser.SamAccountName + " (user was in disabled objects OU but did not have a disabled date.)") | |
159 | ||
160 | $Date = "DISABLED ON " + (Get-Date) | |
161 | Set-ADUser -Identity $DisabledOUUser.SamAccountName -Replace @{ExtensionAttribute3=$Date} | |
162 | ||
163 | #Sets the variable for comparison in the rest of the loop. It was null. | |
164 | $DisabledOUUser.ExtensionAttribute3 = $Date | |
165 | } | |
166 | ||
167 | #Extracts the date disabled for comparison. | |
168 | #If disabled by hand, count from the disable date | |
169 | If ($DisabledOUUser.ExtensionAttribute3 -like "DISABLED ON*"){ | |
170 | $DateDisabled = [datetime]($DisabledOUUser.ExtensionAttribute3.Replace('DISABLED ON ','')) | |
171 | $DaysDisabled = (New-TimeSpan -Start $DateDisabled -End (Get-Date)).Days | |
172 | } | |
173 | #If auto-disabled because of inactivity, add an extra 30 days to account for that so that we are counting from date disabled rather than last activity date. | |
174 | ElseIf ($DisabledOUUser.ExtensionAttribute3 -like "INACTIVE SINCE*"){ | |
175 | $DateDisabled = [datetime]($DisabledOUUser.ExtensionAttribute3.Replace('INACTIVE SINCE ','')) | |
176 | $DaysDisabled = (New-TimeSpan -Start $DateDisabled.AddDays(30) -End (Get-Date)).Days | |
177 | } | |
178 | Else {Write-Error ($DisabledOUUser.SamAccountName + " has an invalid disable date in ExtensionAttribute3.")} | |
179 | ||
180 | #Increment through OUs | |
181 | If ($DaysDisabled -ge 30 -and $DaysDisabled -le 180 -and $DisabledOUUser.DistinguishedName -notlike "*OU=30-180 Days,OU=Users,$ParentOU"){ | |
182 | Write-Output ("Moving user to the 30-180 Days OU: " + $DisabledOUUser.SamAccountName) | |
183 | Move-ADObject -Identity $DisabledOUUser.DistinguishedName -TargetPath "OU=30-180 Days,OU=Users,$ParentOU" | |
184 | $30to180DayMovedUsers++ | |
185 | } | |
186 | Else { | |
187 | If ($DaysDisabled -gt 180 -and $DisabledOUUser.DistinguishedName -notlike "*OU=Over 180 Days,OU=Users,$ParentOU"){ | |
188 | Write-Output ("Moving user to the Over 180 Days OU: " + $DisabledOUUser.SamAccountName) | |
189 | Move-ADObject -Identity $DisabledOUUser.DistinguishedName -TargetPath "OU=Over 180 Days,OU=Users,$ParentOU" | |
190 | $180DayMovedUsers++ | |
191 | } | |
192 | } | |
193 | } | |
194 | ||
195 | #COMPUTERS | |
196 | #Declares counts for output. | |
197 | $30to180DayMovedComputers = 0 | |
198 | $180DayMovedComputers = 0 | |
199 | ||
200 | ||
201 | #Loops through computers and checks if older than 90 days. | |
202 | ForEach ($DisabledOUComputer in $DisabledOUComputers){ | |
203 | #Sets the date disabled if not already set | |
204 | If ($DisabledOUComputer.ExtensionAttribute3 -eq "" -or $DisabledOUComputer.ExtensionAttribute3 -eq $null){ | |
205 | Write-Output ("Setting ExtensionAttribute 3 for Computer: " + $DisabledOUComputer.SamAccountName + " (computer was in disabled objects OU but did not have a disabled date.)") | |
206 | ||
207 | $Date = "DISABLED ON " + (Get-Date) | |
208 | Set-ADComputer -Identity $DisabledOUComputer.SamAccountName -Replace @{ExtensionAttribute3=$Date} | |
209 | ||
210 | #Sets the variable for comparison in the rest of the loop. It was null. | |
211 | $DisabledOUComputer.ExtensionAttribute3 = $Date | |
212 | } | |
213 | ||
214 | #Extracts the date disabled for comparison. | |
215 | $DateDisabled = [datetime]($DisabledOUComputer.ExtensionAttribute3.Replace('DISABLED ON ','')) | |
216 | $DaysDisabled = (New-TimeSpan -Start $DateDisabled -End (Get-Date)).Days | |
217 | ||
218 | #Increment through OUs | |
219 | If ($DaysDisabled -ge 30 -and $DaysDisabled -le 180 -and $DisabledOUComputer.DistinguishedName -notlike "*OU=30-180 Days,OU=Computers,$ParentOU"){ | |
220 | Write-Output ("Moving computer to the 30-180 Days OU: " + $DisabledOUComputer.SamAccountName) | |
221 | Move-ADObject -Identity $DisabledOUComputer.DistinguishedName -TargetPath "OU=30-180 Days,OU=Computers,$ParentOU" | |
222 | $30to180DayMovedComputers++ | |
223 | } | |
224 | Else{ | |
225 | If ($DaysDisabled -gt 180 -and $DisabledOUComputer.DistinguishedName -notlike "*OU=Over 180 Days,OU=Computers,$ParentOU"){ | |
226 | Write-Output ("Moving computer to the Over 180 Days OU: " + $DisabledOUComputer.SamAccountName) | |
227 | Move-ADObject -Identity $DisabledOUComputer.DistinguishedName -TargetPath "OU=Over 180 Days,OU=Computers,$ParentOU" | |
228 | $180DayMovedComputers++ | |
229 | } | |
230 | } | |
231 | } | |
232 | ||
233 | #SUMMARY OUTPUT | |
234 | #Writes the counts of what was modified etc. | |
235 | Write-Output "TOTALS:" | |
236 | $MovedUsers = $MovedUsers.tostring() | |
237 | Write-Output ($MovedUsers + " users were moved to the 0-30 Days OU.") | |
238 | $MovedComputers = $MovedComputers.tostring() | |
239 | Write-Output ($MovedComputers + " computers were moved to the 0-30 Days OU.") | |
240 | Write-Output "" | |
241 | $30to180DayMovedUsers = $30to180DayMovedUsers.tostring() | |
242 | Write-Output ($30to180DayMovedUsers + " users were moved to the 30-180 Days OU.") | |
243 | $30to180DayMovedComputers = $30to180DayMovedComputers.tostring() | |
244 | Write-Output ($30to180DayMovedComputers + " computers were moved to the 30-180 Days OU.") | |
245 | Write-Output "" | |
246 | $180DayMovedUsers = $180DayMovedUsers.tostring() | |
247 | Write-Output ($180DayMovedUsers + " users were moved to the Over 180 Days OU.") | |
248 | $180DayMovedComputers = $180DayMovedComputers.tostring() | |
249 | Write-Output ($180DayMovedComputers + " computers were moved to the Over 180 Days OU.") | |
250 | Write-Output "" | |
251 | ||
252 | #ATTRIBUTE CLEANUP | |
253 | #Gets all AD objects outside of the "disabled objects" OU with ExtensionAttribute3 set and clears it. | |
254 | Write-Output "" | |
255 | Write-Output "ATTRIBUTE CLEANUP:" | |
256 | Write-Output "Getting non-disabled objects with ExtensionAttribute3 set..." | |
257 | $NonDisabledUsers = Get-ADUser -Filter * -Properties DistinguishedName,ExtensionAttribute3,SamAccountName,Enabled | Where {` | |
258 | $_.DistinguishedName -NotLike "*$ParentOU" -and ` | |
259 | $_.Enabled -eq $True -and ` | |
260 | $_.ExtensionAttribute3 -ne "" -and ` | |
261 | $_.ExtensionAttribute3 -ne $null ` | |
262 | } | |
263 | $NonDisabledComputers = Get-ADComputer -Filter * -Properties DistinguishedName,ExtensionAttribute3,SamAccountName,Enabled | Where {` | |
264 | $_.DistinguishedName -NotLike "*$ParentOU" -and ` | |
265 | $_.Enabled -eq $True -and ` | |
266 | $_.ExtensionAttribute3 -ne "" -and ` | |
267 | $_.ExtensionAttribute3 -ne $null ` | |
268 | } | |
269 | ||
270 | Write-Output (($NonDisabledUsers.SamAccountName.Count).ToString() + " users were found.") | |
271 | Write-Output (($NonDisabledComputers.SamAccountName.Count).ToString() + " computers were found.") | |
272 | ||
273 | ForEach ($NonDisabledUser in $NonDisabledUsers){ | |
274 | Write-Output ("Clearing ExtensionAttribute3 for user: " + $NonDisabledUser.SamAccountName) | |
275 | Set-ADUser -Identity $NonDisabledUser.SamAccountName -Clear ExtensionAttribute3 | |
276 | } | |
277 | ||
278 | ForEach ($NonDisabledComputer in $NonDisabledComputers){ | |
279 | Write-Output ("Clearing ExtensionAttribute3 for computer: " + $NonDisabledComputer.SamAccountName) | |
280 | Set-ADComputer -Identity $NonDisabledComputer.SamAccountName -Clear ExtensionAttribute3 | |
281 | } | |
282 | ||
283 | Stop-Transcript |