Выполнение этой команды дает мне множество результатов, за исключением.
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}
Он работает и отображает список всех учетных записей с истекшим паролем. Так почему же невозможно отфильтровать «PasswordExpired -eq $ true» в get-aduser, но он находится после канала?
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
Это потому, что команда сама по себе не создает во внутреннем объекте [свойстве] для PasswordExpired
. $_.PasswordExpired - это метод, а не статическое свойство, поэтому его нужно вызывать при заполнении. Из-за (медленной) скорости больших запросов (с таким количеством свойств), -Filter был реализован для уменьшения количества выходных вызовов, а не так, как в object[property] pipeline.
Поэтому нужно а) отфильтровать объекты, как они становятся единым целым в трубе (я бы порекомендовал это, я просто отфильтровываю почти все в [filter-]трубе) или б) отфильтровать текстовый вывод (select-строка).
Тогда "правильным" способом будет то, что вы только что сделали:
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, так что ничего не скрывается, и я могу отсортировать/поискнуть результат в дальнейшем.
.Похоже на глюк в 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))"
$users= get-aduser -properties DisplayName,Name,PasswordExpired -Filter {Enabled -eq $true}
$users|where {$_.PasswordExpired -eq "True"}|Export-Csv c:\ExpiredPasswordUsers.csv -NoClobber -NoT