colbyt
colbyt

Reputation: 547

Filter by two properties with Get-ADUser

Get-ADUser -SearchBase "OU=Purgatory,DC=domain,DC=com" -Filter {'enabled -eq $false' -and 'whenChanged -lt $ChangeDate'}

I cant figure out how to filter by two traits. I want to filter by disabled users that are older than the $ChangeDate variable. If I filter just by 'enabled -eq $false', it works, and if I filter just by 'whenChanged -lt $ChangeDate' , it works. But if i use the -and to combine them, no luck.

Upvotes: 1

Views: 5047

Answers (1)

mklement0
mklement0

Reputation: 437803

Generally, you should avoid the use of script blocks ({ ... }) as -Filter arguments.

Ultimately, whatever is passed to the -Filter parameter is a string, and using { ... } only obscures that fact, because it falsely suggests that the enclosed expression is a piece of PowerShell code - it is not; it is a severely constrained, PowerShell-like language described in Get-Help about_ActiveDirectory_Filter

What muddies the waters is that the AD provider happens to recognize simple variable references (e.g., $ChangeDate) in the strings it ultimately receives (and use of { ... } effectively passes ... as a string literal), whereas any expression (e.g., $ChangeDate.Year) is not recognized.

  • Generally, the safest approach is to use expandable (interpolating) strings (double-quoted; "...") as -Filter arguments and "bake in" variable values; that is, PowerShell replaces the variable references with their values before the AD provider sees the string.

  • However, it's unclear how date values must be represented inside such a string in order to be recognized as such, so taking advantage of the variable interpretation offered by the AD provider happens to be the safest choice in this case (note the use of single quotes ('...'), which means that the string is passed as-is - PowerShell performs no interpolation):

Get-ADUser -SearchBase "OU=Purgatory,DC=domain,DC=com" `
  -Filter 'enabled -eq $false -and whenChanged -lt $ChangeDate'

Again, be aware that you're passing a string literal to -Filter, and that it is the AD provider interpreting the embedded variable references, which only works with simple variable references, not expressions.


As for what you tried:

{'enabled -eq $false' -and 'whenChanged -lt $ChangeDate'} is effectively passed by calling the .ToString() method on it, which passes everything between the { and } as-is.

That is, the cmdlet / AD provider sees
'enabled -eq $false' -and 'whenChanged -lt $ChangeDate'
as the string value, including the single quotes, which is not what you intended.

Upvotes: 1

Related Questions