Get-aduser 密码过期过滤器无法正常工作

Get-aduser 密码过期过滤器无法正常工作

运行此命令会给我带来大量结果,正如预期。

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

但如果我运行这个命令:

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

我没有得到任何结果

但是当我执行get-aduser test.user -Properties *并查看 PasswordExpired 字段时,它显示“True”。

因此我尝试在过滤器中使用“True”而不是 $true

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

我还是没有得到结果。

但如果我像这样运行它:

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

它能正常工作并列出所有密码已过期的帐户。那么为什么 get-aduser 中无法过滤“PasswordExpired -eq $true”,但它却在管道后面呢?

    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 

答案1

这是因为 cmdlet 本身不会在内部为 创建一个 object[property] PasswordExpired。$_.PasswordExpired 是一个方法,而不是一个静态属性,因此必须在其填满时调用它。由于大查询(具有那么多属性)的速度(缓慢),因此实施了 -Filter 以减少输出调用,这与 object[property] 管道的方式不同。

因此你必须 a) 当对象在管道中成为一个对象时对其进行过滤(我推荐这样做,我只是过滤[filter-]管道中的几乎所有内容)或 b) 过滤文本输出(select-string)。

那么“正确”的方法就是你刚才做的方法:

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

在大多数情况下,我个人使用 | select-object FOO | Out-GridView,因此没有任何内容被隐藏,之后我可以对结果集进行排序/搜索结果集。

答案2

似乎是 cmdLet 出了问题。没有直接属性来指示密码的过期状态。因此,虽然这似乎是一个简单的问题,但有几个可变因素可以确定状态。每个帐户都有一个密码上次更改日期的属性。您可以运行自己的查询,这样会更高效,并且不会给 LDAP 服务器带来太多负载。

$pwAge = 30 # adjust this as needed to match your domain password policy
$oldPassDate = ((get-date).adddays(-$pwAge)).ToFileTimeUtc()

# Ldap notes
# ADS_UF_ACCOUNTDISABLE 0x0002  2
# ADS_UF_DONT_EXPIRE_PASSWD 0x10000 65536
# Ldap bitwise AND = 803
# Ldap bitwise OR = 804

# This Ldap query asks for:
# User objects that last set their password at least 30 days ago
# and do not have "password never expires" or the disabled flags set
get-adobject -ldapFilter "(&(objectCategory=person)(objectClass=user)(pwdlastset<=$oldPassDate)(!userAccountControl:1.2.840.113556.1.4.804:=65538))"

答案3

$users= get-aduser -properties DisplayName,Name,PasswordExpired -Filter {Enabled -eq $true}
$users|where {$_.PasswordExpired -eq "True"}|Export-Csv c:\ExpiredPasswordUsers.csv -NoClobber -NoT

相关内容