17

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?

Bob
  • 2,569
  • 3
  • 26
  • 22

7 Answers7

20

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.

Neobyte
  • 3,179
  • 1
  • 26
  • 31
  • Just curious what means absense of any value for PasswordLastSet... Does it 100% mean that there was no change since password was set initially? – Mikhail Dec 30 '13 at 08:25
  • I don't have a box to test it on, but I think it's more likely that no password has been set on the object yet. – Neobyte Feb 23 '14 at 21:56
  • @Mikhail, most of the time absense of any value for PasswordLastSet means tha you do not run the command in an elevated prompt. – JPBlanc Jun 17 '14 at 09:44
14

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.

Bratch
  • 432
  • 4
  • 12
  • 1
    I've been on a kick to do various simple tasks in PowerShell to try to learn syntax. I was kinda depressed that everywhere I looked the answer was use an add-in. Thanks! – Bob Aug 27 '09 at 22:29
5

There's an easier way.

The ADSI object has a method called ConvertLargeIntegerToInt64. Note that it's a method of the ADSI object and not the System.__Comobject that's returned by querying the value of a timestamp attibute, so $user.pwdLastSet.value.ConvertLargeIntegerToInt64() won't work. You need to invoke it as follows:

$user.ConvertLargeIntegerToInt64($user.pwdLastSet.value)

That will get you the LDAP timestamp, which needs to be converted to a readable date, as explained by Bratch above. This will work for any timestamp attribute value returned by the ADSI provider, and the ConvertLargeIntegerToInt64 method is (I believe) exposed by any object representing a directory entry.

Putting it all together, here is how you get the date when the password was last set:

$user = [ADSI]'LDAP://cn=someusername,ou=someou,dc=somedomain,dc=com'
[datetime]::FromFileTime($user.ConvertLargeIntegerToInt64($user.pwdLastSet.value))
Adi Inbar
  • 61
  • 1
  • 2
3

Here is an easy way to display the AD Computers:

Get-ADComputer -Filter *  -Properties name,LastLogonDate,PasswordLastSet,modified,modifyTimeStamp |
  FT Name,DNSHostName,LastLogonDate,PasswordLastSet,modified,modifyTimeStamp | 
    Out-File Computers.csv
jscott
  • 24,484
  • 8
  • 79
  • 100
William
  • 31
  • 1
1

Install: http://www.quest.com/powershell/activeroles-server.aspx

open powershell

Run the following commands:

add-PSSnapin quest.activeroles.admanagement

Get-QADUser |ft displayname,PasswordLastSet

The first command loads the quest snapin you just downloaded. You don't need to do this if you use the shortcut to quest in your startmenu. The second command gets a list of all the and the users and the time there password was last changed.

1

Add the ConvertADSLargeInteger function to your script, you can get it here:

PowerShell: Convert Active Directory IADSLargeInteger to System.Int64

Here's how you would use it:

$user = [adsi] "LDAP://cn=user1,ou=Staff,ou=User Accounts,dc=ramalamadingdong,dc=net"
[datetime]::FromFileTimeUtc((ConvertADSLargeInteger $user.pwdlastset.value))
0

perhaps you should look at using the passwordLastChanged property. Look here for further info: http://www.microsoft.com/technet/scriptcenter/resources/qanda/aug06/hey0801.mspx

mrTomahawk
  • 1,119
  • 1
  • 10
  • 17