Powershell – Get-aduser Password Expired Filter not working correctly

active-directorypowershell

Running this command gives me loads of results, as excepted.

Get-Aduser -Properties * -Filter {PasswordExpired -eq $false}

But if i run this command:

Get-Aduser -Properties * -Filter {PasswordExpired -eq $true}

I don't get any result

But when i do a get-aduser test.user -Properties * and look at the PasswordExpired field it says "True".

So i try it using 'True' instead of $true in the filter

Get-Aduser -Properties * -Filter {PasswordExpired -eq 'True'}

I still dont get a result.

But if i run it like this:

Get-Aduser -filter {enabled -eq $true -or enabled -eq $false} -Properties * | where {$_.PasswordExpired -eq $true}

It works and lists all the accounts with password expired. So how come it's not possible to filter "PasswordExpired -eq $true" in get-aduser but it is after a pipe?

    PSVersion                      4.0                                                                                                                                       
WSManStackVersion              3.0                                                                                                                                       
SerializationVersion           1.1.0.1                                                                                                                                   
CLRVersion                     4.0.30319.34209                                                                                                                           
BuildVersion                   6.3.9600.17400                                                                                                                            
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0}                                                                                                                      
PSRemotingProtocolVersion      2.2 

Best Answer

That is because the cmdlet itself does not create in internal object[property] for PasswordExpired. $_.PasswordExpired is a method, not a static property so it has to be called when its filled. Because of the (slow) speed of big queries (with that number of properties), the -Filter was implemented to reduce the output-calls, not the same way as the object[property] pipeline.

So you have to a) filter the objects as they become one in the pipe (I would recommend this, I just filter almost everything in [filter-]pipes) or b) filter the text output (select-string).

The 'correct' way then would be the way you just did it:

Get-ADUser -Properties * -Filter * | `
   # to get the whole object(s), most simple way
   # You can make the query faster here, by getting less properties
   #   -Properties Name,PasswordExpired -Filter *
? { $_.PasswordExpired -eq $false } | `
   # here it became an $_.property,
   # just filter what you need from the object stream
ft Name,PasswordExpired
   # do some output

In most cases I personally use | select-object FOO | Out-GridView, so nothing gets hidden and I can sort/search the resultset afterwards.