|
|
|||||||
I'm using the following script to compile a list of users and their login scripts. This helps us identify which login scripts are being used and also finding any users who don't have a login script assigned. Here's the script: code:The script works great to retrieve the users from the OU specified. The problem is, under the OU "USA" there are sub OU's for almost every state and then each of those has one or more sub OU's containing user IDs. Is there anyway to have the script search all sub OU's underneath any given "root" OU and return the same info? I know that I could hard code an array of target OU's and loop through that, but we're talking about possibly 100's of OU's and 1000's of users.Break ON Thanks. |
||||||||
|
|
|||||||
When you GETOBJECT on the users OU, your enumeration should also enumerate the other OU objects. You should check the "class" of each object. If the class is "user" then get and report your properties. Otherwise, You should perform another GETOBJECT on the OU to enumerate it. This would be a good use for a recursive UDF. |
||||||||
|
|
|||||||
Howard, if it's not too much to ask could you elaborate a little bit? A lot of this is new to me and I'm now lost . If it's too much trouble, or too detailed to go into I understand. Thanks. |
||||||||
|
|
|||||||
I will provide you a code sample later today. I am currently working on some time sensitive items. |
||||||||
|
|
|||||||
JohnQ, Hate to "steal Howard's thunder!" Here is another way to do this, no LDAP needed. Borrowing from the follwing topics: Re-Write of the KIX32.EXE Deployment tool MS-Tech Article findings- 318689 We can take the code to modify the users from NTLOGON and change it to look for Domain Users that have no script. code:HTH,CLS Kent |
||||||||
|
|
|||||||
Shame on you for trying that! $count = EnumOUs("LDAP://NetbiosDomain/DC=us, DC=MyCompany, DC=com", "computer") or $count = EnumOUs("LDAP://NetbiosDomain/DC=us, DC=MyCompany, DC=com", "user") [ 16. May 2003, 20:07: Message edited by: Howard Bullock ] |
||||||||
|
|
|||||||
Radimus already has a UDF in the UDF Library: EnumOUs() - Enumerates OUs containing Users or Computers |
||||||||
|
|
|||||||
The basis of the code I provided is from - setting a user's login script. Thanks, Kent |
||||||||
|
|
|||||||
Howard, Your function works great but I have two questions. 1. When using the "user" filter, it still returns computers as well. 2. If I wanted to spit out the user's login script (or some other attribute), where the heck would I put that in your function? Thanks for all of your help from the "scripting challenged". |
||||||||
|
|
|||||||
There seems to be a problem with the IADsContainer FILTER property. In this function the filter works properly for "group", "computer", and "container", but returns computer objects of both 'user' and 'computer' classes when the FILTER is set to "user". This may be related to the fact that computer accounts are indeed hidden user account "computer$", but that should not be the issue since the object definitely return the class "computer" when the FILTER is to "user". I have added additional code to validate that the object class is indeed the specified and desired class of object the function was sent to enumerate. See the "if $Class = $Filter" construct. Also I have an oversight when enumerating the complete domain for users. The object called "Users" is in fact of class "container". So the code was modified to recurse on objects of both classes: 'organizationalUnit' and 'container'. The $aFilter array was Redim'ed and the extra filter added. [ 17. May 2003, 14:47: Message edited by: Howard Bullock ] |
||||||||
|
|
|||||||
Oh, for your second question: you would add a line to get the loginscript property and place the value into a variable with $Name = $item.Name $Class = $item.Class and then add the variable to the out line. [ 17. May 2003, 01:52: Message edited by: Howard Bullock ] |
||||||||
|
|
|||||||
Please see More on perceived FILTER problem for some insights into the problem where Computers are returned when the FILTER is set to "user". |
||||||||
|
|
|||||||
Thanks Howard. One last question...If you wanted to get the value of a custom optional object property within a class, how would you go about getting that? Example: code:The problem here is the dash in abc-emplCode. And $item.'abc-emplCode' returns nothing. Any suggestions?$ecode = $item.abc-emplCode |
||||||||
|
|
|||||||
that sounds like kixtart problem. as once you write a operator there kixtart assumes it has a math sentence... |
||||||||
|
|
|||||||
Is there any way that you know of to get around it? Unfortunately, I can't remove the dash. |
||||||||
|
|
|||||||
A long-shot, no AD here: $Value = $Object.Get("Property-Name") |
||||||||
|
|
|||||||
Try: $ecode = $item.get("abc-emplCode") or $ecode = $item.getex("abc-emplCode") {edit} I hate when people stop at my desk and ask questions. It makes my posts late. {edit again} Lonkero, Your post has made me feel all warm and fuzzy now. [ 21. May 2003, 01:26: Message edited by: Howard Bullock ] |
||||||||
|
|
|||||||
hoby, does it make you stop hating if I say I love you? |
||||||||
|
|
|||||||
Thanks Howard and Shawn. Using $item.get("abc-emplCode") worked like a champ. |
||||||||
|
|
|||||||
There is one other user property that I would like to be able to retrieve from AD and this is if the "password never expires" checkbox is checked. I have tried using $item.PasswordExpirationDate but it returns nothing. Am I searching for the wrong thing. |
||||||||
|
|
|||||||
You need to perform bitwise operations for that data. See the documetation for AdminMisc.DLL for some additional data. http://mywebpages.comcast.net/habullock/Win32Admin.htm#User More data: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netdir/adsi/modifying_user_properties.asp [ 21. May 2003, 05:24: Message edited by: Howard Bullock ] |
||||||||
|
|
|||||||
Here are some good script examples that can be converted to KiXtart Script Center - Users and Groups http://www.microsoft.com/technet/treeview/default.asp?url=/technet/scriptcenter/user/default.asp TechNet Script Center http://www.microsoft.com/technet/treeview/default.asp?url=/technet/scriptcenter/Default.asp |
||||||||
|
|
|||||||
Howard's DLL is probably the easiest way to deal with PasswordNeverExpires property. However, you can work with it, but you need to plug in values to set/remove it. http://userpages.umbc.edu/~kbradl1/wsz/ref/ADSIref.html HTH, Kent |
||||||||
|
|
|||||||
Howard, thanks for the info on obtaining the "password never expires" setting. One question about that though...Why is $flags set in the following manner: $flags & 65536 instead of $flags = 65536? Also, in one of your previous posts, you mentioned using GetEx instead of Get. What's the diff? Thanks so much for all of your help. |
||||||||
|
|
|||||||
The documentation states: quote: quote:The difference: quote: quote:The User_Flags value is one of those items that stores many different properties. Using an equal sign to set the value as in your example would change the settings of all the other properties. The syntax ($flags & 65536) check the current setting it does not set the value or flag. You would have to do a bitwise OR $flags = $flags | 65536 to set the value. Please read my Win32Admin.DLL help or search the MSDN for more detail on User_Flags. In short each bit of the number represents a flag. It can be a "1" or a "0". The postion of the bit gives it its decimal value. I think that User_Flags is a 3 byte (24 bit) field. The example below uses 2 bytes (16 bits). As you can see above changing the value of 4117 to some other multiple of 2 would set the other bits to "0" changing more than you wanted to change. Read up on Binary operation if necessary. [ 22. May 2003, 14:33: Message edited by: Howard Bullock ] |
||||||||
|
|
|||||||
Staying with the subject here... Does anyone know what the class property is to determin if an account is disabled? I looked at all of the properties in Howard's EnumObjProps function, but there are so many it's hard to tell which one it might be. I just thought that maybe someone had searched this one out before. |
||||||||
|
|
|||||||
I always thought it was: code:if $user.accountdisabled |
||||||||
|
|
|||||||
That was discussed here yesterday. http://www.kixtart.org/board/ultimatebb.php?ubb=get_topic;f=1;t=007210 |
||||||||
|
|
|||||||
I you are using the LDAP:// provider then the property and access is somewhat different. $Flags = $objUser.Get("userAccountControl") Then the bitwise operation must be performed on this value. code:if $Flags & 2 [ 22. May 2003, 17:10: Message edited by: Howard Bullock ] |
||||||||
|
|
|||||||
Howard, the EnumOUs() UDF that you provided works great and I have modified it for various things and use the heck out of it. My question is, and forgive me for my ignorance, what is the purpose of $i and $j? $J obviously causes recursion after each container is exhausted, but I don't understand bumping the count of $i and then later resetting $i to $i + $j. It doesn't seem to be used anywhere and seems to work fine without using $i. Could you briefly explain if you have a moment? Thanks |
||||||||
|
|
|||||||
It is simply a counter. $i is incremented by one for each name that is printed. the final value of $i is then returned to the calling script (recursion) ($EnumOUs = $i). This value is placed into $j of the calling function. $j which represents the total count of all recursions for a particular bracnch is then added to $i in the current loop. After all recursion is exhausted and the original function call exists to the script $i will return a count of all names seen. |
||||||||
|
|
|||||||
Howard, I certainly don't mean to question you, but how can $i ultimately return the total number of items seen if $i and $j are both reset to 0 each time recursion occurs? |
||||||||
|
|
|||||||
Because the function returns the number of elements each time it's called. |
||||||||
|
|
|||||||
The variables are SCOPED within the function: Function EnumOUs($LDAP, $Filter) ;$Filter = 'computer' | 'user' dim $aFilter[0], $pos, $objOU, $i, $j This means that the variables $i and $j exists multiple times independently in each recursively called instance of the EnumOUs function. Each value is used within that instance of the function and returned to parent instance via "$EnumOUs = $i" statement. If this post does not clarify the issue, please let me know and I will try to explain it better. |