So today I discovered that the LastLogonTimestamp attribute of an account in AD (also known as LLTS) is only updated on logon if the old value is more than 14 days in the past. That means the value can only be trusted if it is more than 14 days in the past.

This, as it turns out, is very annoying if you’re trying to do some semi-half-assed auditing. Now, you can use the LastLogon attribute, which is always up to date, but that isn’t replicated between DCs so you have to query all of them.

Note to my future self: Do not rely on LLTS for anything more recent than 14 days.

The following will get all account lockout events from all writable domain controllers in the current domain and output the information to a text file. Active Directory Powershell Module is required.

ipmo activedirectory;$(Get-ADDomainController -Filter  {(OperatingSystem -ne "") -and (IsReadOnly -ne "True")} | %{Get-WinEvent -ComputerName $ -LogName security -FilterXPath "*[System[EventID='4740']]" | Select machinename,TimeCreated,@{Label='User Name';Expression={$_.Properties[0].Value}},@{Label='Client Name';Expression={$_.Properties[1].Value}}}) | Out-File C:\temp\lockout.txt

Windows has a centralised logging facility for applications; the Windows Event Log. If you’re writing applications for Windows then for the love of God please use it properly.

DO create your own event message DLL(s) where appropriate to avoid your events looking like this

DO log important errors and warnings. Application failures, communication issues, invalid configuration data and the like. Things that will help administrators to troubleshoot issues that may occur.

DO make your logs intelligible to someone other than you. Not having developed the application myself, I have no way of knowing if “Invalid foo in bar. More cheese needed at 0x8003387” means that someone’s made a typo in a config file somewhere, a firewall rule needs changing or that the application doesn’t support running during the vernal equinox.

DO throttle your logging. Don’t log the same error every second, it’s pointless, generates a lot of “noise” and – much worse – forces other, potentially useful events out of the log’s retention.

DO make your logging level easily configurable by the user and DO set a sensible default.

DON’T log every single informational or debug event that your application generates. Nobody gives a shit that you successfully checked a message queue and found it was empty; either use a Custom Event Log or a log file in the application directory if you want to record that kind of information.