In one of many DevOps automation testing environments I work with I lately got here throughout an AD OU that had over 75,000 unused pc information. This setting is used for repeated testing of whole automation stacks with distinctive pc names, so it’s regular that these information would pile up. Whereas this specific OU was for Linux machines – the issue clearly affected each Home windows and Linux throughout all OUs.
Being that it’s the 12 months 2018 I assumed discovering a ready-made answer on the internet could be youngster’s play (oh Murphy – why do you plant these ideas in my head!).
As it’s with the Toolsmithing nature, after I couldn’t discover a easy answer, I had a powerful need to conjure a instrument for everybody.
Because of the years lengthy must purge inactive pc area be a part of information, there are numerous current options. Many of those options are a part of a software program product that requires set up or a part of industrial PowerShell modules. Others are pages lengthy scripts that take time to evaluation to make sure they get solely what I want them to However an extended standing dedication to favor utilizing solely what ships on the field drove me to seek out one thing that didn’t require third social gathering or full-on software program installations – and if attainable not even PowerShell module installs (as they don’t seem to be simple to perform on all variations of PowerShell).
Listed below are the attributes and advantages of the answer (I believe each you and I respect bullets relatively than paragraphs eh?):
- It solely requires PowerShell 3 and the ActiveDirectory module which is put in on any Area Controller.
- It efficiently runs underneath SYSTEM account within the activity scheduler (eliminating any dependency on admin credentials encoded into the scheduled activity)
- You’ll be able to configure the purge threshold (what number of days for the reason that machined logged onto the area)
- It has a report solely mode to be able to audit precisely what is going to occur when working underneath the duty scheduler because the SYSTEM account (Learn “GOTCHA!” beneath.)
- It generates a report file of every run so you possibly can audit what it has performed (however provided that it has work to do)
- Writes log to the $env:public folder to keep away from the necessity for additional code to create a folder and to keep away from dropping reviews if temp is cleaned.
This may be scheduled as SYSTEM on a site controller – creates a CSV of no matter was tried to be eliminated. AFTER RUNNING A TEST REPORT SCHEDULED UNDER SYSTEM ACCOUNT, Change $PurgeThreshold
to lower than 10 years and set $ReallyDelete
to $True
. It is vitally, essential that the times are unfavourable – in any other case all pc information can be focused.
$ReallyDelete = $False ; $PurgeThreshold = -3650 ; $RemoveList = @(Search-ADAccount -AccountInactive -DateTime (get-date).AddDays($PurgeThreshold) -ComputersOnly) ; If ($RemoveList.rely -lt 1) {Exit 0} ; $RemoveList | Kind-Object LastLogonDate | Choose-Object Title, LastLogonDate, DistinguishedName, SID, ObjectGUID | Export-Csv -NoTypeInformation -Path "$env:publicAD-ComputerCleanUp-At-$(Get-date -format 'yyyyMMddHHmm').csv" ; If ($ReallyDelete) Take away-ADComputer -Verify:$False
Be aware: It’s best to get the code from the repository hyperlink on the backside as copying from a browser is a infamous approach to introduce unusual artifacts into your code.
Sure it’s a very lengthy oneliner and the semi-colons technically aren’t what is supposed by oneliner – however I wished a single line as a result of it permits setting it up within the activity scheduler with out having to transit a separate file. If you want, you possibly can retailer it as a file and tidy it up for human readability. It may also be run on the command line to check the report.
The code makes use of the Search-ADAccount CMDLet which has the flexibility to seek out inactive pc accounts. If there aren’t any computer systems to purge, the code exits. If there are computer systems to course of the code will generate a CSV report of what it’s about to try deleting. Lastly, if $ReallyDelete = $True
, it’s going to really delete the pc information.
-
Set
$ReallyDelete = $False
, set$PurgeThreshold
to a price that’s more likely to solely generate a small variety of goal machines. -
Run the code in an interactive immediate and evaluation the generated report file to make sure the code is focusing on precisely what was supposed. Alter your threshold to focus on lower than 100 machines.
-
With the identical settings…
- on ONLY ONE area controller,
- create a scheduled activity to run as SYSTEM with no password
- set the schedule to be repeating – however
- set the primary execution to be days sooner or later.
Be aware: Don’t delete the identical pc information on a number of DCs. Utilizing SYSTEM prevents the dangerous safety apply of embedding credentials. If you don’t run on a DC, you have to area admin credentials outlined within the scheduled activity.
-
Proper click on and pressure run the duty to run.
-
Assessment the generated report file to make sure the code is focusing on precisely what was supposed (the identical small set of machines).
-
Replace the duty to set
$ReallyDelete = $True
and re-force run the duty. -
Study the report AND Lively Listing to confirm outcomes.
-
Replace the duty with the long run worth for
$PurgeThreshold
-
Drive run the duty once more in order that the primary massive purge occurs whereas you’ll be able to audit. IMPORTANT: In case you have numerous information to initially delete, it could be smart to do them in smaller batches with time for AD to sync in between each. You’ll be able to play with reporting mode on a command line to determine what dates create what batch sizes after which run a number of batches over a interval of days in order to not push too many deletes suddenly.
Particular Case: A number of Scheduled Cases
If you wish to run this on a number of DCs for resilience, be sure that the roles have sufficient elapsed time between execution in order that AD replication will happen from the primary scheduled activity earlier than the subsequent runs. It will be greatest if this elapsed time is in days – not hours – particularly for environments with many DCs. When calculating elapsed time, don’t overlook to account for timezone variations of DCs in several timezones.
Area joined Home windows machines have a consumer identify (pc identify with “$” on the tip) and commonly logon to the area to maintain their area belief relationship lively. By default Home windows modifications this password each 30 days. If the machine just isn’t logging in commonly, this password change ends in a damaged belief. To reestablish area membership the machine have to be take away and re-added to the area. This is the reason it’s thought of secure to forcibly take away a machine from the area if it has not logged in 30 days.
Nonetheless! If your organization has prolonged this worth or disabled it on some computer systems resulting from rare area connectivity (e.g. VM templates/snapshots, very distant staff) – then 30 days is likely to be too quickly for you. It’s necessary to know if this worth is being managed in certainly one of these prolonged methods to have the ability to decide the suitable window. Take note if that is working on a schedule, there’s not must get uptight about getting these machines out as quickly as attainable – so long as people who exceed the brink are being robotically purged – it shouldn’t matter how lengthy that threshold is as a result of it doesn’t require human consideration.
I ran right into a severe gotcha with Search-ADAccount that I can’t clarify – however that almost sunk me. When first prototyping the command I used the -TimeSpan parameter with the set variety of days I wished to purge. Once I ran it from an interactive command line to report on the machines it could delete I acquired 31. Once I ran the delete in the identical context it eliminated solely 31 machines. I then modified the times parameter to get about 50 machines and ran it underneath the SYSTEM account on a site controller. For some purpose it listed each machine within the area from this context. I’ve seen many odd behaviors when working code as SYSTEM and/or underneath the scheduler – however this one may have been disastrous.
I refactored the code to make use of the -DateTime parameter and it labored identically in an interactive command immediate and underneath the scheduler utilizing SYSTEM account.
This bolstered a number of disciplines I attempt to preserve conscious of:
- At all times take a look at the EXACT execution context of your code earlier than turning it on.
- Do super-paranoid testing when that code does mass deletes of any kind.
- By no means assume that the duty scheduler nor SYSTEM account context are going to behave the identical as interactive testing underneath an admin account.
- From the FIRST LINE OF CODE – create an audit or whatif mode for any code that may have devastating operational penalties – it helps you debug the code in addition to being a greatest apply for every day operations of the code. This concept is, in some methods, akin to Check Pushed Growth (TDD).
This code will be simply modified altered to:
- disable inactive information for a time period earlier than deletion (though it could be simply as simple to create an extended threshold worth like 1 12 months).
- purge unused consumer accounts – with consumer accounts there’s not an computerized interval of dormancy that will point out they’re unused – so watch out right here.