Event 4: My notes…

Active Directory is one of those things I just love to work with. That’s why I was looking forward to the entries in this particular event. I found out few things I was not aware of while reading some of the entries, but also seen some mistakes that I would like to highlight. As always: I will start with Beginner category “positives”, and move on until I get to “negatives” in Advanced category.

Before I dig into code, one comment for toolsets used. There were basically three ways: ADSI, Quest, AD module. These days either should work. But I was shocked to see some comments (accompanied with 1* rating) claiming that Quest tools have more limitations than AD module from Microsoft… On contrary! It has 0 requirements both on AD and client side and AD module is not “built in”. You should be aware, that ADWS is built in only in DCs running Windows Server 2008 R2 (and later). It can be installed on down-level DCs, but Quest will run fine without ADWS. Also, it’s impossible to install RSAT (AD module is part of it) on older systems, Quest can be installed on XP and above (and because you can’t installed PowerShell on anything older anyways – that’s hardly a limitation). Next: most version of Quest cmdlets require PowerShell v1, something that for AD module (hint – hint – modules were added in v2) can’t even be considered. Finally – you don’t have to buy anything to use it. If you buy Active Roles Server you have to use Quest cmdlets, but that does not work other way around. So if you want some arguments against Quest – use speed, or “3rd party” demon. But not price or portability… Puszczam oczko

Beginners: awesome!

I must say that I liked the fact that many users decided to be smart and avoid working to hard on it. It’s not like we need to have very detail info here, or use very portable code. Many entries used very good subset of user’s properties that required very little work on their side (LastLogonDate, PasswordLastSet, Lockout, Enabled). I also liked the fact that some people actually decided to make sure they are picking up random from all users and used –ResultSetSize/ PageSize/ –SizeLimit. I also noticed that some folks know exactly how to handle booleans (-not $_.Enabled). Finally – last logon date. It was tricky, but I’ve seen few entries that used combination of lastlogon and lastlogontimestamp to get relatively good result very quickly.

Beginners: not cool…

Time to complain. Puszczam oczko First of – Get-ADUser –Property *. If you need only few properties, why do you insist on getting all of them, for all users in AD? Next: if you want to get user from current domain, specifying root is not necessary. And it makes code domain-specific, without real benefit.

Another “pack” of issues is related to getting random user. Get-Random was used most of time but some people wanted to do it hard way:

  • pass Get-Random to sort’s script block
  • add index to each user and “draw” numbers
  • build reach object for each user in domain before picking up random group

Finally: I’ve seen entries that took advantage of AD module, but ignored the fact, that it comes with some benefits… Calculating properties if there is one calculated already is really waste of time here.

Advanced: awesome!

Very short list here… not because script were not great. Many of them were really awesome. But to pick some special elements – that was hard part. Didn’t wanted to repeat everything again: validation, pipeline, help – most of you get it. So what I liked in this event? I Liked few ideas for getting random users quicker. Also – liked when people tried to get accurate value for lastLogon, especially if they’ve used separate function for this operation.

Advanced: not cool…

If you read my previous entry you probably guessed it by now: I love to use ADSI directly. But I’ve noticed some people do it (in my opinion) hard way… Use full classes names, don’t use constructor other than default one, do not use –Property parameter for New-Object cmdlet, no using of [class]@{ properties } syntax (or I simply missed it). Pity.

Next: lastlogon… I didn’t pay too much attention to it in beginners category, but here…? Common! You have to be aware, that this property may be empty for some users. Do you really want to inform auditors, that some of your users logged to the system in the first day of 17th century?

Next: account locked out. If you rely on userAccountControl – you are doing it wrong. If you rely on lockouttime only, you will miss the fact that locks expire after certain time (to be more specific: after time defined in lockout duration). Good news is that lockouttime will at least give you hint. There are some other ways to figure it out, but important thing to remember: useraccouncontrol –band 0x10 is not correct answer. Puszczam oczko

This leads me to next point: mixed mode. If you depend on Active Directory module (e.g. use Search-ADaccount) than ignore ADSI, use AD module all the way. I don’t see any benefits in using ADSI if you plan to use cmdlets at some point anyways.

And finally, if you use ADSISearcher, you can use properties it retrieves most of the time, no need to use GetDirectoryEntry method.

Few more things

I just wanted to add few more things that I’ve seen that were not major issues, but not very nice either. First of all – using break. It really has it’s purpose. Using it to exit from script or return from function (bolds are hints Puszczam oczko ) is in my opinion very bad idea. You can read more here. Long story short: break should be used in loops, where it belongs.

Next: variables. Storing whole AD in single variable, just to throw most of it away soon after – bad idea.

Backtick… If you are in the middle of construct that can be easily broken into several lines – don’t use backtick. It’s really easy to miss it’s there, and break the code by single space next too it. If you are listing things, you can always put newline after comma, and backtick won’t be needed anymore.

Finally: walking around in circles. Why would you:

[DateTime]::FromFileTimeUtc($lastlogon).ToLocalTime()

You can get local time in first method call (just use different method). Why punish yourself? Puszczam oczko Nothing really bad, just not optimal. And that’s it for today. Have fun writing scripts for event number 5!

1 thought on “Event 4: My notes…

  1. Pingback: Event 4: My notes… | PowerShell.org

Leave a comment