运行此命令会给我带来大量结果,正如预期。
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