A Tale of Two Cmdlets

In my past few columns, I’ve been talking about the Active Directory (AD) tool called search-adaccount. This is a command that you’ll appreciate more and more as you continue to explore it. Need to find locked-out users in a particular OU? Easy. Want to know who hasn't logged on in 110 days? Piece of cake. Want to find all of the disabled users in a given OU and retrieve their managers' names so that you can report the accounts to their bosses via email? No prob—oh.

OK, I take that back. That is a problem. Apparently, search-adaccount can find those users, but it can't tell you their manager's name … or those users' titles … or those users' given names … or just about any of the 100-plus attributes that every AD user object contains. The problem is solvable, but let me back up and explain a bit more.

Thus far, you've met two of Windows Server 8 R2's AD-serving PowerShell cmdlets: Get-ADUser and search-adaccount. Get-ADUser, the beefier of the two cmdlets, lets you describe in great detail what sort of users you're trying to extract from AD. That's great, but it carries the cost of fairly complex syntax. The AD folks apparently knew that, however, and must have feared that Get-ADUser would scare would-be AD PowerShellers, so they built a “junior partner” cmdlet for Get-ADUser called search-adaccount. Search-adaccount can perform only a small percentage of the queries that Get-ADUser can, but its syntax far less scary than Get-ADUser's. If that sounds like it might be a bad tradeoff, trust me, it isn’t: Although the range of things that you can query search-adaccount for is small, those queries are some of the most popular. Search-adaccount can find accounts with expired passwords, locked-out accounts, disabled accounts, inactive accounts, expired and about-to-expire accounts, and accounts with passwords that never expire. Add that to search-adaccount's much smaller list of parameters, and you end up with a cmdlet that’s quite a bit easier for AD PowerShell types to figure out than Get-ADUser. (But let's be clear: I'm not suggesting you give Get-ADUser a pass, as that would be a big mistake. Any AD admin will need it regularly.)

You’ve also seen that after Get-ADUser does its job, it returns just 17 of the 110 attributes and properties associated with an AD user account, but you can fix that by adding the -properties parameter (or -pr) to the Get-ADUser statement, as in

get-aduser -f "title -like 'teach*'" -properties office,title

That query would return the 17 standard properties of users, as well as the office and title properties. Remember also that you can get a list of the particular properties that Get-ADUser (or any other cmdlet) provides by piping its output into the cmdlet Get-member (or gm) as in

get-aduser -f "title -like 'teach*'" -properties office,title | gm

Now try piping search-adaccount's output to Get-member to see what search-adaccount offers in the way of properties. Use this query, which should work on any AD implementation because, by default, every AD environment has a disabled account named guest and another named krbtgt:

search-adaccount-accountdisabled -usersonly|gm

A quick look at Get-member's output will show that it's even stingier with information than Get-ADUser's defaults, with just 13 properties revealed. So how would you, for example, extract the title or office of an account retrieved by search-adaccount? My first thought was that search-adaccount must have a -properties parameter like Get-ADUser's, but unfortunately that’s not the case. How, then, to get search-adaccount to cough up all the details of an account? The answer is simple: Enlist the aid of Get-ADUser. For example, to see all your disabled user accounts and to see their titles and offices, type

The first part of that code finds all the user accounts that are disabled. Then, the pipe (|) says to put those user accounts into the pipeline, feeding them as inputs to the command that follows. The final portion tells Get-ADUser to go get those user accounts from AD, and when it displays the accounts, it should show not only the basic 17 attributes but also the office and title attributes. It's a nice workaround for a cmdlet limitation, but for the sake of completeness I should mention that the Get-ADUser command ends up being a trifle redundant, as it re-queries AD for those disabled accounts. But the number of disabled accounts will probably be fairly tiny compared with the total number of accounts, so it's not a terrible redundancy. Oh, and in case you've been wondering, you can send email messages from PowerShell, using the send-mailmessage command. But I'll cover that another day.

At my company, we have three terminal servers and every time we sign up a new client, my boss throws out user accounts like there is no tomorrow. Therefore, I am quite positive we have tons of accounts have never been used and may or may not be disabled.
So now what I need to do is take this article and write a PowerShell scheduled task that keeps me updated, via email, of all accounts that have not been logged on to in 30 days or are disabled from my terminal server OU.
Thanks Mark!
JamesNT