• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 879
  • Last Modified:

How to set account expiration policy?

I have a particular OU for which I would like to define an account expiration policy. That is, if the account is not used for a certain length of time (say, 90 days), the account will automatically be disabled.

I know that I can do this with a password expiration period, but the problem is that these users do not log into the domain- they use a token-based password with IAS for RADIUS authentication into non-domain UNIX servers.

Can this be done?
0
mikebernhardt
Asked:
mikebernhardt
  • 13
  • 11
1 Solution
 
LauraEHunterMVPCommented:
Create a scheduled task to run oldcmp (free command-line tool downloadable from www.joeware.net), which will programmatically disable accounts that have been inactive for X number of days.  You can home the search on a specific OU, and even have oldcmp automatically move those users to a Disabled Users OU" or something.

Hope this helps.

Laura E. Hunter - Microsoft MVP: Windows Server - Networking
0
 
mikebernhardtAuthor Commented:
That is a way useful tool, but not in the intended way. The users in question NEVER log into the domain, they only use IAS. Running  a user report demonstrated that IAS logins are not tracked in AD. It showed last login as months ago, or never. So it will not let me know about which accounts have not used IAS in particular.

I wonder if there's a way to audit IAS against AD to see which users have NOT been logged?
0
 
LauraEHunterMVPCommented:
Ah, I see what you're trying to do.  You're right, oldcmp won't suffice there.

Hmmm.  I'm not an IAS person, but I do know that you can log requests to a SQL database or at least some sort of CSV file.

If so, here's how I would work around it - though keep in mind that an IAS whiz might say "Man that's a strange workaround, here's how I'd do it in all of my IAS guru-ness.":

[1] Run a "SELECT DISTINCT" query (or some kind of grep or regex against a CSV file) on 90 days' worth of logs to get every username that has logged in during that time. Dump the info to a text file, one username per line.

[2] Disable every account in the "IAS Users" OU. (You'll see why in a second.) Depending on your SLA with this service this may require a user announcement like "The WayCool web service will be unavailable from 1am-2am on the 15th of every month for maintenance."  You can use adfind & admod (two other way useful tools from joeware.net) to do this using a syntax similar to the following: (careful, line will probably wrap in your window - it's all a single command)

adfind -default -rb "ou=IAS Users" -f "(&(objectcategory=person)(objectclass=user))" -dsq | admod -sc uacset:ACCOUNTDISABLE

[3] Take the filename containing the list of accounts that -have- logged on in the last 90 days (see where I'm going?) and re-enable only those accounts using something similar to the following: (again, all one line even if it wraps in the browser window. Also, if you're going to put this into a batch file instead of manually typing it at the command line, replace the instances of '%h' below with '%%h')

for /f %h IN ("c:\users.txt") DO adfind -default -rb="ou=IAS Users" -f "(&(objectcategory=person)(objectclass=user)(sAMAccountName=%h)" -dsq | admod -sc uacclear:ACCOUNTDISABLE

The reason for doing it this way is that the logic is much simpler to take an action against every account that you know HAS logged in, rather than taking a list of accounts and comparing it against a larger list to figure out which ones HAVEN'T logged in and then disabling those.  The former, as you can see, is one line of batch and joeware commands (or probably a dozen lines of vbscript if that's your thing). The latter would involve multiple queries and string comparisons and probably a sort or two...if you can stand to have all the IAS users disabled for the 10 minutes it'll probably take for this to run, I'd do it the easy way.

0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
mikebernhardtAuthor Commented:
That is a very interesting approach that I will look into. The affected group is not that large. I know Perl and could easily write a script that would parse the log file for users that successfully logged in, and even probably automate the rest of it (by invoking the adfind utility). I'd probably run it duringlunch on a business day when the users are generally unlikely to need to log in.

Hmmm, I'll get back to you on that!
0
 
LauraEHunterMVPCommented:
Oh yeah, parsing the IAS log file with perl would take like 3 lines of code from all the Perl I've seen.  (Never learned it myself, since there's only so many hours in a day and the stack of cmputer books waiting for me them to read is taller than I am -already-. :-))
0
 
mikebernhardtAuthor Commented:
Here's a question: When I run the command you gave me:
adfind -default -rb "ou=IAS Users" -f "(&(objectcategory=person)(objectclass=user))" -dsq

I get a list of users in the OU I named. But it doesn't provide me with the sAMAccountName, which is what I really want (it's easier to use since it doesn't have spaces, etc.). Is there a way to extract those with the output? I've been trying but I don't understand the syntax well enough.
0
 
mikebernhardtAuthor Commented:
Really, those userids are the only output I need...
0
 
LauraEHunterMVPCommented:
So you don't need the distinguished name in the output at all?  Just the sAMAccount name?

Try this: adfind -default -rb "ou=IAS Users" -f "(&(objectcategory=person)(objectclass=user))" -nodn sAMAccountName

If you still need the DN in addition to the samaccount, just leave out the "-nodn" switch.
0
 
mikebernhardtAuthor Commented:
No, that's perfect! I'm working on the script...
0
 
mikebernhardtAuthor Commented:
OK, here's another question about admod: What I want to do with my script is, once I've identified a user to disable, I want to just run admod to do it if possible- using the SAMAccountName if possible. So assuming the SAMAcountName was "joe" (and if needed, the OU is "folks") how can I accomplish that? My understanding of AD is very limited, thus all these usage question.
0
 
LauraEHunterMVPCommented:
admod requires a distinguished name to perform an operation.  If you have the samaccountname, you can use adfind to grab the correct DN and then pipe the output to admod.  I showed you an example of piping in an earlier comment assuming a slightly different context - for what you're looking for it'll be something like this: (assuming that you've defined a variable of %USERNAME% as the samaccountname that you're looking for.)

adfind -default -rb="ou=IAS Users" -f "(&(objectcategory=person)(objectclass=user)(sAMAccountName=%USERNAME%)" -dsq | admod -sc uacclear:ACCOUNTDISABLE

-sc uacset:ACCOUNTDISABLE will disable the account
-sc uacclear:ACCOUNTDISABLE will enable the account (under the hood you are -clearing- the ACCOUNTDISABLE flag, and thus enabling the account.)
0
 
mikebernhardtAuthor Commented:
So if I want to run the command substituting a specific username for %USERNAME%, then I would assume this is the syntax. but I get an error:

C:\>adfind -default -rb "ou=IAS Users" -f "(&(objectcategory=person)(objectclass=user)
(sAMAccountName="blin")" -dsq | admod -sc uacclear:ACCOUNTDISABLE

AdMod V01.10.00cpp Joe Richards (joe@joeware.net) February 2007

ldap_get_next_page_s: [netadmin-dc2.netadmin.domain.com] Error 0x57 (87) - Filter Error
DN Count: 0

But if I run adfind to locate the same user, it works:
C:\>adfind -default -rb "ou=IAS Users" -f "(&(objectcategory=person)(objectclass=user)
(SAMAccountName="blin"))" -nodn SAMAccountName

AdFind V01.36.00cpp Joe Richards (joe@joeware.net) February 2007

Using server: netadmin-dc2.netadmin.domain.com:389
Directory: Windows Server 2003
Base DN: ou=FCE,DC=netadmin,DC=bart,DC=gov

>sAMAccountName: blin

1 Objects returned

No object DNs to update.

The command completed successfully.
0
 
LauraEHunterMVPCommented:
Hmmmm.  Try removing the -dsq switch, I may have been wrong in including that.  The -dsq switch is used if you want to take adfind output and pipe it to one of the built-in MS command-line tools like dsmod - maybe admod doesn't need it if you're piping -from- a joeware tool -to- a joeware tool.  (Sometimes even _I_ have trouble remembering all the switches.  :-))
0
 
mikebernhardtAuthor Commented:
Nope, removing that causes a syntax error.
0
 
LauraEHunterMVPCommented:
HA!  Got it.  (I told you even I don't remember all the switches, esp. since joe just added the uacset and uacclear options like a month ago.)

Behold, the correct syntax, just tested it on my home server:

adfind -default -rb="ou=IAS Users" -f "(&(objectcategory=person)(objectclass=user)(sAMAccountName=%USERNAME%)" useraccountcontrol -adcsv | admod -sc uacclear:ACCOUNTDISABLE
0
 
LauraEHunterMVPCommented:
Grrrrr.  One last time without the typo, shall we?

adfind -default -rb "ou=IAS Users" -f "(&(objectcategory=person)(objectclass=user)(sAMAccountName=%USERNAME%)" useraccountcontrol -adcsv | admod -sc uacclear:ACCOUNTDISABLE
0
 
mikebernhardtAuthor Commented:
Still no love :-(

Here's what I entered, because I'm trying to disable a specific username:
adfind -default -rb "ou=FCE" -f "(&(objectcategory=person)(objectclass=user)(sAMAccountName="blin")" useraccountcontrol -adcsv | admod -sc uacclear:ACCOUNTDISABLE

I'm getting the same "Filter Error" message as before. Note that the above includes the actual OU that the user belongs to. I tried it with and without quotes around the user name.

The way that I'm actually going to implement this is that when the script finds someone who's userid has a count of 0 logins, it will run the above command to disable their account. so for testing purposes it should work with an actual username instead of a variable.
0
 
LauraEHunterMVPCommented:
If you've copied your command string verbatim, you're missing a closing parenthesis on the LDAP filter - should read "(sAMAccountName=blin))"

I don't think you need the inner quotes around the sAMAccountName, but can't remember off the top of my head if that creates a separate error.
0
 
mikebernhardtAuthor Commented:
That was it! I think I am on my way, I'm going to give you the points now. Thanks for much for your help!
0
 
mikebernhardtAuthor Commented:
Actually, I copied YOUR command verbatim and it's missing the closing parentheses :-)
0
 
LauraEHunterMVPCommented:
D'oh!  Didn't happen, nobody saw it happen, you can't prove a thing.  (Oh, wait, you can, it's in the Google cache by now.  Poo.  ;-)
0
 
mikebernhardtAuthor Commented:
One last question: Is it possible to search for members of a security group instead of an OU? It would be some sort of modification of this:
adfind -default -rb "ou=IAS Users" -f "(&(objectcategory=person)(objectclass=user))" -nodn sAMAccountName

Assume the group is called IAS.

If you'd prefer I open a new question I will do that as soon as I hear back from you.
0
 
LauraEHunterMVPCommented:
Nah, you were patient with my multiple typos, that's fine.  :-)

So you want to pull the members of a security group and pipe the member list to admod, rather than the users contained in an OU?  Am I understanding you?

This is a 5-second answer off the top of my head, so tell me if it doesn't work and I'll go digging. I'm pretty sure that if you know the distinguished name of the group you can do this:

adfind -b cn=IAS,ou=Groups,dc=domain,dc=com -asq member | admod blah blah blah

It's called an "attribute-scoped query" - each group has a "member" attribute that can contain multiple values, and you're querying for the values contained in that attribute.
0
 
mikebernhardtAuthor Commented:
That did the trick, thanks!
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 13
  • 11
Tackle projects and never again get stuck behind a technical roadblock.
Join Now