Powershell: How do I query pwdLastSet and have it make sense?

I need to get the last password change for a group of account in an Active Directory security group, and I feel like this is something PowerShell should be good at.

Right now, I'm already stuck at how to read the pwdLastSet attribute from the AD account I'm looking at. Even running something simple like this:

[adsi] "LDAP://cn=user1,ou=Staff,ou=User Accounts,dc=ramalamadingdong,dc=net" | Format-List *

gives results for pwdLastSet that appear like this:

pwdLastSet            : {System.__ComObject}

I feel like I'm go about this the wrong way, so what's the best way to query and then format the output (the value is based on the Windows Epoch and not very human readable) of the pwdLastSet attribute?


Solution 1:

You can also do this without a snap-in. I tried this and it worked:

PS #> $searcher=New-Object DirectoryServices.DirectorySearcher
PS #> $searcher.Filter="(&(samaccountname=user1))"
PS #> $results=$searcher.findone()
PS #> [datetime]::fromfiletime($results.properties.pwdlastset[0])

Wednesday, June 10, 2009 4:32:08 PM

I also get a System.__ComObject for pwdLastSet if I have the user object set like this:
$user = [adsi] "LDAP://cn=user1,ou=Staff,ou=User Accounts,dc=ramalamadingdong,dc=net"

There should be a way to use [System.__ComObject].InvokeMember() and reflection to get that pwdLastSet value from the $user object, but I haven't been able to get it right. I never did figure it out, so I used the above example and moved on.

If you're going to be doing a lot of work with AD (or Exchange or SQL Server) you might want to get the snapin for it and use that.

Solution 2:

The inbuilt AD commandlets that come with Windows 7/Windows Server 2008 R2 can now do this simply enough. On Windows 7 from a Powershell prompt:

Import-Module ActiveDirectory
Get-ADUser 'user1' -properties PasswordLastSet | Format-List

The "PasswordLastSet" atribute appears to be a translated version of the actual "pwdLastSet" attribute.