AD cleanup

4 views
Skip to first unread message

Heaton, Joseph@Wildlife

unread,
Dec 13, 2018, 11:41:27 AM12/13/18
to ntsys...@googlegroups.com

I have an automated process that disables and moves accounts, when they go inactive for 45 days.  For computers, I wait another 45 days, then delete the AD object.  The second part of this has been a very manual, intensive process, where I open each object, go to the attribute editor tab, and look at lastlogin and lastlogintimestamp.  If both of these are 90+ days old, I manually delete the account.  Now, ultimately, I’d like to get to the point of having a script that does all this for me, but right now, I’m looking to take baby steps.  Is there anyway to display Last Login and Last Login Timestamp, as columns in ADUC?  I’ve looked at the custom query area, as well, but was thinking that if I was going to do that type of query, I may as well just go Powershell and work on the final script itself.

 

Joe Heaton

Information Technology Operations Branch

Data and Technology Division

CA Department of Fish and Wildlife

1700 9th Street, 3rd Floor

Sacramento, CA  95811

Desk:  916-323-1284

 

Coleman, Hunter

unread,
Dec 13, 2018, 11:45:11 AM12/13/18
to ntsys...@googlegroups.com

Have you considered using oldcmp.exe? https://www.joeware.net/freetools/tools/oldcmp/index.htm

 

That can handle the reporting, moving, and deleting based on any criteria you want to set up.

--
You received this message because you are subscribed to the Google Groups "ntsysadmin" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ntsysadmin+...@googlegroups.com.
To post to this group, send email to ntsys...@googlegroups.com.
Visit this group at https://groups.google.com/group/ntsysadmin.
To view this discussion on the web visit https://groups.google.com/d/msgid/ntsysadmin/MW2PR0901MB2411E83C395F749B245BA656AAA00%40MW2PR0901MB2411.namprd09.prod.outlook.com.
For more options, visit https://groups.google.com/d/optout.

Heaton, Joseph@Wildlife

unread,
Dec 13, 2018, 11:47:27 AM12/13/18
to ntsys...@googlegroups.com

I forgot all about that one.  I actually started the automated process I mentioned with that tool, then we bought Netwrix, which does the 45 day thing for me.  I’ll go back and look at that again, thanks so much!

Amanda Appleton

unread,
Dec 13, 2018, 11:48:21 AM12/13/18
to ntsys...@googlegroups.com
Personally I'd skip the ADUC column step and go straight to powershell. Export the data to a csv, manually check the relevant columns then delete them and save just the samaccountname out to csv and run another powershell script to delete everyone in the csv.


For more options, visit https://groups.google.com/d/optout.

Southbank Centre
Belvedere Road
London
SE1 8XX



Registered Charity No. 298909

Michael B. Smith

unread,
Dec 13, 2018, 11:55:12 AM12/13/18
to ntsys...@googlegroups.com

Cavete! Hic sunt dracones!

 

[Beware! Here be dragons!]

 

I just cringe when I read things like this (sorry, not because of you). J

 

Do you have AD Recycle Bin enabled? If not, go do that, first thing. J

 

There are objects in your AD which will never be logged into and may even be disabled that you never want to delete.

 

For users: Administrator (maybe), krbtgt, guest, lots of Exchange objects.

 

For computers: any cluster’s CNO and VNOs, the Azure AD SSO object, etc.

 

There may be others. These are the first things that pop to mind.

 

Forget ADUC. Go straight to PS. But you still need to be very careful.

 

From: ntsys...@googlegroups.com [mailto:ntsys...@googlegroups.com] On Behalf Of Heaton, Joseph@Wildlife
Sent: Thursday, December 13, 2018 11:41 AM
To: ntsys...@googlegroups.com
Subject: [ntsysadmin] AD cleanup

 

I have an automated process that disables and moves accounts, when they go inactive for 45 days.  For computers, I wait another 45 days, then delete the AD object.  The second part of this has been a very manual, intensive process, where I open each object, go to the attribute editor tab, and look at lastlogin and lastlogintimestamp.  If both of these are 90+ days old, I manually delete the account.  Now, ultimately, I’d like to get to the point of having a script that does all this for me, but right now, I’m looking to take baby steps.  Is there anyway to display Last Login and Last Login Timestamp, as columns in ADUC?  I’ve looked at the custom query area, as well, but was thinking that if I was going to do that type of query, I may as well just go Powershell and work on the final script itself.

--

Heaton, Joseph@Wildlife

unread,
Dec 13, 2018, 11:59:21 AM12/13/18
to ntsys...@googlegroups.com

I completely understand your cringing, no worries.  Yes, we have the AD Recycle Bin enabled, and keeping objects for 180 days.  The computer objects I’m referring to are desktops and laptops only, no servers.  Same thing with the user accounts, no service accounts, no built-in accounts, etc.  The OUs are selected carefully for the 45-day inactivity portion.  The process has been in place for several years now, but the final deletion has always been a manual (by me) process, and I’d like to at least get away from having to open each computer account individually, and look at the login entries.  Not looking to develop anything that is set and forget at this point.

Michael B. Smith

unread,
Dec 13, 2018, 12:02:18 PM12/13/18
to ntsys...@googlegroups.com

Then I also like oldcmp. The html report looks dated, but it’s a great summary, and once you’ve vetted the data, it handles the cleanup cleanly and easily.

Kurt Buff

unread,
Dec 13, 2018, 1:41:28 PM12/13/18
to ntsys...@googlegroups.com
I'll second the comments of others (Amanda and Michael) - there are
any number of powershell AD cleanup scripts out in the world. Just
point one of them at the relevant OUs, make sure that the script will
first move them to a disabled accounts OU for the waiting period, then
have it clean up that OU.

Heck, it's not even a really complicated script to write yourself.
I've done it, so it can't be too hard...

Kurt

Heaton, Joseph@Wildlife

unread,
Dec 13, 2018, 4:40:54 PM12/13/18
to ntsys...@googlegroups.com

So, I did a couple of things.

 

  1. I exported all the computers in my disabled computers OU.  I manually trimmed the CSV, to show just Name and Last Login date.  I manually trimmed that, to just machines that showed 9/14 and older (90 days).  I came up with 53 machines.
  2. I ran oldcmp.exe -report -format csv, leaving all defaults, which is supposed to be 90 days.  The report had 100+ machines.
  3. I took these reports, limited the columns to just Name, put it into Beyond Compare, to see the differences.

 

A number of the machines picked out by oldcmp had much newer dates than 9/14, so not 90 days old.

Coleman, Hunter

unread,
Dec 13, 2018, 5:53:36 PM12/13/18
to ntsys...@googlegroups.com

lastLogon is not a replicated attribute, so if your export process got its information from one DC and oldcmp got its information from a different DC, you should expect to see the results you found.

 

Use lastLogonTimestamp instead, which is replicated. Note, though, that you will want to pad your stale window a bit to account for the “loose” updating mechanism for lastLogonTimestamp.

Heaton, Joseph@Wildlife

unread,
Dec 13, 2018, 7:08:54 PM12/13/18
to ntsys...@googlegroups.com

That’s the funny thing.  From the powershell export, the attribute name is LastLogonDate, which is actually Last Logon Timestamp, when looking in ADUC.  Not sure what oldcmp is looking at, but, as I mentioned, the “extra” machines that oldcmp came up with were machines where both Last login and last logon timestamp were newer dates than 90 days ago.

Kurt Buff

unread,
Dec 13, 2018, 8:25:24 PM12/13/18
to ntsys...@googlegroups.com
I believe that ADUC is a bit screwy - I'd rely on powershell.

I have 4 DCs - two in the US (dc1 and dc2), where I am, and one each in our UK (dc3) and AU (dc4) offices.

# get-adcomputer -server dc1 -Identity us-it-kbuffvm -properties lastlogon, lastlogondate, LastLogontimeStamp, PasswordLastSet | select Name, (@{Name="LastLogon"; Expression={[DateTime]::FromFileTime($_.LastLogon).ToString("u")}}), (@{Name="LastLogonDate"; Expression={$_.LastLogonDate.ToString("u")}}), (@{Name="LastLogonTimeStamp"; Expression={[DateTime]::FromFileTime($_.LastLogonTimeStamp).ToString("u")}}), PasswordLastSet | ft -auto

Name          LastLogon            LastLogonDate        LastLogonTimeStamp   PasswordLastSet
----          ---------            -------------        ------------------   ---------------
US-IT-KBUFFVM 2018-12-13 12:27:11Z 2018-12-06 13:28:40Z 2018-12-06 13:28:40Z 2018-12-05 22:37:21



# get-adcomputer -server dc2 -Identity us-it-kbuffvm -properties lastlogon, lastlogondate, LastLogontimeStamp, PasswordLastSet | select Name, (@{Name="LastLogon"; Expression={[DateTime]::FromFileTime($_.LastLogon).ToString("u")}}), (@{Name="LastLogonDate"; Expression={$_.LastLogonDate.ToString("u")}}), (@{Name="LastLogonTimeStamp"; Expression={[DateTime]::FromFileTime($_.LastLogonTimeStamp).ToString("u")}}), PasswordLastSet | ft -auto

Name          LastLogon            LastLogonDate        LastLogonTimeStamp   PasswordLastSet
----          ---------            -------------        ------------------   ---------------
US-IT-KBUFFVM 2018-12-13 17:00:57Z 2018-12-06 13:28:40Z 2018-12-06 13:28:40Z 2018-12-05 22:37:21



# get-adcomputer -server dc3 -Identity us-it-kbuffvm -properties lastlogon, lastlogondate, LastLogontimeStamp, PasswordLastSet | select Name, (@{Name="LastLogon"; Expression={[DateTime]::FromFileTime($_.LastLogon).ToString("u")}}), (@{Name="LastLogonDate"; Expression={$_.LastLogonDate.ToString("u")}}), (@{Name="LastLogonTimeStamp"; Expression={[DateTime]::FromFileTime($_.LastLogonTimeStamp).ToString("u")}}), PasswordLastSet | ft -auto

Name          LastLogon            LastLogonDate        LastLogonTimeStamp   PasswordLastSet
----          ---------            -------------        ------------------   ---------------
US-IT-KBUFFVM 1600-12-31 16:00:00Z 2018-12-06 13:28:40Z 2018-12-06 13:28:40Z 2018-12-05 22:37:21



# get-adcomputer -server dc4 -Identity us-it-kbuffvm -properties lastlogon, lastlogondate, LastLogontimeStamp, PasswordLastSet | select Name, (@{Name="LastLogon"; Expression={[DateTime]::FromFileTime($_.LastLogon).ToString("u")}}), (@{Name="LastLogonDate"; Expression={$_.LastLogonDate.ToString("u")}}), (@{Name="LastLogonTimeStamp"; Expression={[DateTime]::FromFileTime($_.LastLogonTimeStamp).ToString("u")}}), PasswordLastSet | ft -auto

Name          LastLogon            LastLogonDate        LastLogonTimeStamp   PasswordLastSet
----          ---------            -------------        ------------------   ---------------
US-IT-KBUFFVM 2018-11-09 02:01:04Z 2018-12-06 13:28:40Z 2018-12-06 13:28:40Z 2018-12-05 22:37:21






Reply all
Reply to author
Forward
0 new messages