Active Directory Clean Up

Maybe there's already a way to do this easily, but I haven't found it yet. It seems like it should be quite a common problem that many organizations have and I'm almost certain that Windows does something to aid IT Administration with it. I need a way to easily remove user accounts automatically after, say, 90 days of inactivity (no logins for 90 days). Any suggestions?
sngarrardAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

WerewolfTACommented:
You might not want to delete them but rather disable them.  That way, you're preventing them from logging in, but should you ever need to reactivate them, you can just enable the account, rather than resetting up everything, like security group memberships, etc.

I too would like to find something that would do this.  Unfortunately, if you have more than one DC, this doesn't seem to be possible.  As the article below describes (or at least the part I can see without paying), the last logon time isn't replicated between the DC's, meaning you'd have to check that value on each DC.

http://www.winnetmag.com/WindowsScripting/Article/ArticleID/40885/40885.html

Unless you have only 1 DC, which I would never advise unless you're a really small shop, the best you could probably hope for would be to do some scripting that would run against each DC every day and send you the reports.  Then, you could hand check or manipulate the data in another program.
oBdACommented:
Here's a commercial product:
Unused Account Ferret: Overview
http://www.anixis.com/products/uaf/default.htm

Do you have the W2k Resource Kit (namely usrstat.exe)?
sngarrardAuthor Commented:
I do have W2K Resource Kit. I also have 2 DCs which could potentially be a problem. Disable or deleting these inactive users would be great.
oBdACommented:
You can use the lodump.cmd script (written for a similar purpose) as first step; it uses usrstat.exe, removes conflicting entries, and creates four output files:
lodump-All.log (to be precise: <whatever-you-decide-to-name-the-command-file>-All.log), with all logon dates, lodump-060.log, with all logon dates older than about (the date calculation is rather crude) 60 days; lodump-090.log and -120.log respectively. All of the files are created always (that is to say: if there's no entry, the file will be there, it will just have a size of zero). Old files will be overwritten without further warning. There are four ";"-separated entries in each line: logon date, logon time, username and servername.
Just change the date delimiter according to the one that's used in your system, and adjust the sequence the day, month and year are put into the variables.
You can then check the file that's of interest for you (lodump-090.log in your case) if it really only contains accounts that can be deleted (you can easily import this into Excel or whatever).
Then you can use the second script to delete or disable the user accounts found in the log file. Note that the script is currently running in test mode; it will only display the commands it would otherwise run, so that you can check if it runs properly. Remove the "ECHO" where indicated to run it for real.
As usual: No warranties included, use it at your own risk, test it before you apply it in earnest.

====8<----[loDump.cmd]----
@echo off
setlocal
rem *** Split ages in days (use multiples of 30)
set Age01=060
set Age02=090
set Age03=120
rem *** Name of the output files:
set OutFileAll=%~n0-All.log
set OutFile01=%~n0-%Age01%.log
set OutFile02=%~n0-%Age02%.log
set OutFile03=%~n0-%Age03%.log
rem *** Date delimiter of "date /t" command:
set DateDelim=/
rem *** New date delim, for use in output files:
set NewDateDelim=-

rem *** XP and Server 2003 omit the day in "date /t":
set DateToken=2,3,4
ver | find "XP" && set DateToken=1,2,3
ver | find "Version 5.2" && set DateToken=1,2,3

rem *** Adjust date sequence if necessary:
for /f "tokens=%DateToken% delims=%DateDelim% " %%a in ('date /t') do (
 set CurMon=%%a
 set CurDay=%%b
 set CurYear=%%c
)

rem *** Remove a possible leading zero:
if %CurMon:~0,1%==0 set CurMon=%CurMon:~1%
rem *** Calculate the split dates:
call :SplitDate %Age01% 01
call :SplitDate %Age02% 02
call :SplitDate %Age03% 03

set TempFile=%~dpn0.tmp
set OldUser=

if exist "%OutFileAll%" del "%OutFileAll%"
usrstat %UserDomain% >"%TempFile%"
for /f "tokens=1*" %%a in (%TempFile%) do (
 set User=%%a
 set Tail=%%b
 call :process
)
del "%TempFile%"

echo Removing conflicting entries ...
for /f "tokens=1-4 delims=;" %%a in ('sort /r "%OutFileAll%"') do (
 set User=%%a
 set Date=%%b
 set Time=%%c
 set Server=%%d
 call :Duplicate
)

echo Splitting according to age ...
if exist "%OutFileAll%" del "%OutFileAll%"
echo Dummy 1>NUL 2>"%OutFile01%"
echo Dummy 1>NUL 2>"%OutFile02%"
echo Dummy 1>NUL 2>"%OutFile03%"
for /f "tokens=1-4 delims=;" %%a in ('sort "%TempFile%"') do (
 set Date=%%a
 set Time=%%b
 set User=%%c
 set Server=%%d
 call :Split
)
del "%TempFile%"
goto leave

rem **********************************************************************
:SplitDate
set Age=%1
set i=%2
set Year=%CurYear%
:LZLoop
if %Age:~0,1%==0 (
 set Age=%Age:~1%
 goto LZLoop
)
set /a Mon = CurMon - (Age / 30)
if %Mon% LSS 1 (
 set /a Mon += 12
 set /a Year -= 1
)
if %Mon% LSS 10 set Mon=0%Mon%
set SplitDate%i%=%Year%%NewDateDelim%%Mon%%NewDateDelim%%CurDay%
goto :eof

rem **********************************************************************
:process
rem *** usrstat starts the beginning of the dump of a new DC with "Users on \\<somedc>"
if /i not %User%==Users goto ProcessUser

for /f "tokens=2 delims=\" %%a in ("%Tail%") do set Server=%%a
echo Processing logon info on %Server% ...
goto :eof

:ProcessUser
for /f "tokens=1* delims=:" %%a in ("%Tail%") do set LastLogon=%%b
for /f "tokens=1-5" %%a in ("%LastLogon%") do (
 set Day=%%a
 set Month=%%b
 set Date=%%c
 set Time=%%d
 set Year=%%e
)
if /i %Day%==Never (
 set Month=00
 set Date=00
 set Time=00:00:00
 set Year=0000
)
if /i %Month%==Jan set Month=01
if /i %Month%==Feb set Month=02
if /i %Month%==Mar set Month=03
if /i %Month%==Apr set Month=04
if /i %Month%==May set Month=05
if /i %Month%==Jun set Month=06
if /i %Month%==Jul set Month=07
if /i %Month%==Aug set Month=08
if /i %Month%==Sep set Month=09
if /i %Month%==Oct set Month=10
if /i %Month%==Nov set Month=11
if /i %Month%==Dec set Month=12
(echo %User%;%Year%%NewDateDelim%%Month%%NewDateDelim%%Date%;%Time%;%Server%)>>"%OutFileAll%"
goto :eof

rem **********************************************************************
:Duplicate
if /i "%User%"=="%OldUser%" goto :eof
set OldUser=%User%
(echo %Date%;%Time%;%User%;%Server%)>>"%TempFile%"
goto :eof

rem **********************************************************************
:Split
(echo %Date%;%Time%;%User%;%Server%)>>"%OutFileAll%"
if %Date% LSS %SplitDate03% (
 (echo %Date%;%Time%;%User%;%Server%)>>"%OutFile03%"
 goto :eof
)
if %Date% LSS %SplitDate02% (
 (echo %Date%;%Time%;%User%;%Server%)>>"%OutFile02%"
 goto :eof
)
if %Date% LSS %SplitDate01% (
 (echo %Date%;%Time%;%User%;%Server%)>>"%OutFile01%"
 goto :eof
)
goto :eof

:leave
====8<----[loDump.cmd]----

====8<----[UnusedAccounts.cmd]----
@echo off
setlocal
:: *** Path and name of the csv file with users to be deleted/disabled:
set csvFile=C:\Temp\lodump-090.log
:: *** Delimiter used in csv file:
set csvDelim=;
:: *** Token/column number of the user name in the csv file:
set csvToken=3
:: *** Root DN under which to search for the user account to be processed:
set DNRoot=dc=acme,dc=local
:: *** Action to take: set this to disable or delete:
set Action=test

if /i "%Action%"=="disable" goto Start
if /i "%Action%"=="delete" goto Start
goto leave

:Start
for /f "tokens=%csvToken% delims=%csvDelim%" %%a in ('type "%csvFile%"') do call :process "%%a"
goto :leave

:process
set User=%1
for /f "delims=" %%a in ('dsquery.exe user "%DNRoot%" -samid %User%') do set DNUser=%%a
goto %Action%
:disable
:: *** test mode: remove the ECHO in front of the following line to 'arm' the script:
ECHO dsmod.exe user %DNUser% -disabled yes
goto :eof

:delete
:: *** test mode: remove the ECHO in front of the following line to 'arm' the script:
ECHO dsrm.exe %DNUser% -noprompt
goto :eof

:leave
====8<----[UnusedAccounts.cmd]----

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Windows Server 2003

From novice to tech pro — start learning today.