View difference between Paste ID: rjpgGwd7 and nPtGPcfV
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