Time for more Active Directory cleaning!
Last month, in “Use Get-ADUser to Find Inactive AD Users” (InstantDoc ID 141486), I introduced search-adaccount, an AD cmdlet that can tell you which users' accounts are inactive (where "inactive" means the user hasn't logged on for some number of days). This month, I’ll show you more of its syntax, as well as an interesting idiosyncrasy I call "the missing 15 days of search-adaccount."
To find out which accounts haven't logged on in, say, the past 90 or more days, you can type
search-adaccount -usersonly -accountinactive -timespan "90"
Note that you have to pass the "90" to -timespan with the double quotes, or it won't work as you expect and won't offer an error message, which leads to more troubleshooting than most of us want to experience. Another way to define "inactive" is to offer search-adaccount a particular date with the -datetime parameter. To see the users who haven't logged on since, say, December 1, 2011, you could type
search-adaccount -usersonly -accountinactive -datetime "1 December 2011"
Again, note that the date you pass to -datetime must be in quotes. As you learned last month, AD doesn't have an actual "inactive" flag in a user account, so search-adaccount determines whether an account is inactive with an AD attribute called lastlogondate. You can create a table of inactive user accounts by piping search-adaccount output to an "ft" (format table) command like so:
search-adaccount -usersonly -accountinactive -datetime "1 December 2011"|ft samaccountname,lastlogondate –auto
Try that command on a functioning, vibrant Active Directory (AD), however, and play around with a number of different dates or time spans, and you'll start noticing something strange. If you had a user with a lastlogondate of, say, November 30, you'd expect a search-adaccount command with a -datetime "1 December 2011" parameter to catch that account (as November 30, 2011, occurs before December 1, 2011)—but it doesn't. In fact, that command won't report any users with a lastlogondate before approximately November15. Similarly, if you were to do an equivalent command with -timespan parameter, such as
search-adaccount -usersonly -accountinactive -timespan "29"
on December 30, 2011, you'd think that command would pick up everyone whose last logon date was December 1, 2011 (29 days prior to December 30) or earlier, but it doesn't. Instead, it reports only the folks with lastlogondate values around November 15 or earlier. It's as if search-adaccount includes a built-in 15-day grace period. What's up with that? I haven’t talked to search-adaccount's author, but my guess is that it's related to lastlogondate's quirky nature.
You might recall that AD aims to update lastlogondate only once every 14 days, no matter how often you log on in that time period. Microsoft does that because every new value of lastlogondate kicks off some AD replication, and Microsoft fears that more frequent lastlogondate updates might burden your network. Thus, a lastlogondate of November 25, 2011, on a given user's account doesn't really mean that she last logged on November 25, 2011. More specifically, it means that this user's most recent logon might have happened on November 25, or she might have logged on a hundred times between then and December 9 (14 days after November 25), but AD just didn't update her lastlogondate—because it didn't have to. In light of that, you can see that it might be unfair to mark that user's account as inactive solely because of a lastlogondate of November 25, and that in truth "November 25" essentially equals "December 9" in this context. Lastlogondate's "slop factor" is 14 days, so I imagine search-adaccount's author added another day for good measure, and from that, search-adaccount got its 15-day grace period. It certainly seems a good compromise.
Some clients, however, haven't been happy to hear of this, as their legal and compliance folks want their lists of inactive users to reflect actual you-can-print-'em-out values of lastlogondate, and so they want search-adaccount to employ what might be called a strict interpretation of lastlogondate. For those folks, the answer is simple. If you want your inactive list to be close to lastlogondate's actual value, subtract 15 from any -timespan values, and move any -datetime values 15 days into the future. Instead of -timespan "90", use -timespan "75"; instead of -datetime "1 December 2011", use -datetime "16 December 2011".
Search-adaccount -accountinactive does a job that I've not seen other AD tools do as well. Next month, I’ll show you a few more of its tricks!