Срок действия пароля Get-ADUser для пользователей в определенных подразделениях
Я могу получить действительное свойство "msDS-UserPasswordExpiryTimeComputed" для одного пользователя:
(([DateTime]::FromFileTime((Get-ADUser $UserName -Properties "msDS-UserPasswordExpiryTimeComputed")."msDS-UserPasswordExpiryTimeComputed")))
Но у меня проблемы с таргетингом на группу конкретных пользователей. Мой более крупный скрипт предназначен для извлечения различных атрибутов пользователей AD из учетных записей, в частности OU, и их экспорта в CSV. Все свойства заполнены, как и ожидалось, за исключением объекта "PasswordExpiry".
Приведенный ниже пример возвращает фиктивную дату "PasswordExpiry" "31.12.1600" для каждого пользователя. "C:\UserList.txt" содержит sAMAccountNames по одному на строку.
$UserList=Get-Content "C:\UserList.txt"
ForEach ($UserName in $UserList) {Get-ADUser "$UserName" -Properties * |
Select-Object sAMAccountName,whenCreated, `
@{Name="lastLogon";Expression={[DateTime]::FromFileTime($_.lastLogon)}}, `
@{Name="pwdLastSet";Expression={[DateTime]::FromFileTime($_.pwdLastSet)}}, `
@{Name="PasswordExpiry";Expression={[DateTime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")}}, `
cannotChangePassword,passwordNeverExpires, `
@{Name="GroupMember";Expression={($_ | Select -ExpandProperty MemberOf) | Where {$_ -Like "*Desired.Group*"}}} |
Export-Csv -Path "C:\UserInfo.csv" -Append -NoTypeInformation}
Это работает, если я хотел опросить всех пользователей AD:
Get-ADUser -Filter * –Properties sAMAccountName,"msDS-UserPasswordExpiryTimeComputed" |
Select-Object -Property sAMAccountName,@{Name="PasswordExpiry";Expression={[DateTime]::FromFileTime($_.“msDS-UserPasswordExpiryTimeComputed”)}}
Но если я добавлю параметр [-SearchBase "OU=Users,DC=Domain,DC=local"] в Get-ADUser, я получу нулевой вывод для "PasswordExpiry". Я думаю, я мог бы попытаться проанализировать весь вывод с некоторой постобработкой. Похоже, прикосновение больше, чем я должен был хотя.
Я знаю, что могу рассчитать срок действия на основе атрибута "pwdLastSet". Но я хочу получить реальную стоимость, потому что возрастная политика может быть неизвестна. Любая помощь приветствуется.
3 ответа
Я должен был определить свойство в дополнение к "*", чтобы оно работало. Видимо, одной звездочки в этом случае недостаточно.
Get-ADUser -Identity "$UserName" -Properties *,"msDS-UserPasswordExpiryTimeComputed"
Второй пример, который, как мне показалось, работал только без -SearchBase, фактически работал все время. Как подчеркнул Бит Бэкон, я запрашивал только небольшую группу пользователей, у которых срок действия установлен на Никогда. Так что null был допустимым выводом там.
Это не было проблемой с оригинальным сценарием. Вернул "31.12.16" несмотря ни на что. Как уже упоминалось выше, мне пришлось добавить дополнительное свойство, чтобы получить правильные значения. Это хорошо сейчас.
$UserList=Get-Content "C:\UserList.txt"
ForEach ($UserName in $UserList) {Get-ADUser "$UserName" -Properties *,"msDS-UserPasswordExpiryTimeComputed" |
Select-Object sAMAccountName,whenCreated, `
@{Name="lastLogon";Expression={[DateTime]::FromFileTime($_.lastLogon)}}, `
@{Name="pwdLastSet";Expression={[DateTime]::FromFileTime($_.pwdLastSet)}}, `
@{Name="PasswordExpiry";Expression={[DateTime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")}}, `
cannotChangePassword,passwordNeverExpires, `
@{Name="GroupMember";Expression={($_ | Select -ExpandProperty MemberOf) | Where {$_ -Like "*Desired.Group*"}}} |
Export-Csv -Path "C:\UserInfo.csv" -Append -NoTypeInformation}
Get-ADUser -Filter * -SearchBase "OU=Users,DC=Domain,DC=local" –Properties sAMAccountName,"msDS-UserPasswordExpiryTimeComputed" |
Select-Object -Property sAMAccountName,@{Name="PasswordExpiry";Expression={[DateTime]::FromFileTime($_.“msDS-UserPasswordExpiryTimeComputed”)}}
РЕДАКТИРОВАТЬ: Теперь делать это в соответствии с предложением Биты Бекона:
$ListOfOUs="OU=Users01,DC=Domain,DC=local","OU=Users02,DC=Domain,DC=local","OU=Users03,DC=Domain,DC=local"
$ListOfOUs | ForEach {Get-ADUser -Filter * -SearchBase $_ -Properties sAMAccountName,whenCreated,lastLogon, `
pwdLastSet,"msDS-UserPasswordExpiryTimeComputed",cannotChangePassword,passwordNeverExpires,MemberOf |
Select-Object sAMAccountName,whenCreated, `
@{Name="lastLogon";Expression={[DateTime]::FromFileTime($_.lastLogon)}}, `
@{Name="pwdLastSet";Expression={[DateTime]::FromFileTime($_.pwdLastSet)}}, `
@{Name="PasswordExpiry";Expression={[DateTime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")}}, `
cannotChangePassword,passwordNeverExpires, `
@{Name="GroupMember";Expression={($_ | Select -ExpandProperty MemberOf) | Where {$_ -Like "*Desired.Group*"}}} |
Export-Csv -Path "C:\UserInfo.csv" -Append -NoTypeInformation}
Согласно спецификации на msDS-UserPasswordExpiryTimeComputed
:
Атрибут msDS-UserPasswordExpiryTimeComputed существует в AD DS, но не в AD LDS.
Этот атрибут указывает время истечения срока действия пароля объекта. Позволять
TO
быть объектом, на котором атрибутmsDS-UserPasswordExpiryTimeComputed
читается ЕслиTO
не в доменеNC
, затемTO!msDS-UserPasswordExpiryTimeComputed = null
, В противном случае пустьD
быть корнем доменаNC
содержащийTO
,DC
применяет следующие правила, в порядке, указанном ниже, чтобы определить значениеTO!msDS-UserPasswordExpiryTimeComputed
:
Если какой-либо из
ADS_UF_SMARTCARD_REQUIRED
,ADS_UF_DONT_EXPIRE_PASSWD
,ADS_UF_WORKSTATION_TRUST_ACCOUNT
,ADS_UF_SERVER_TRUST_ACCOUNT
,ADS_UF_INTERDOMAIN_TRUST_ACCOUNT
биты установлены вTO!userAccountControl
, затемTO!msDS-UserPasswordExpiryTimeComputed = 0x7FFFFFFFFFFFFFFF
,Остальное, если
TO!pwdLastSet = null
, или жеTO!pwdLastSet = 0
, затемTO!msDS-UserPasswordExpiryTimeComputed = 0
,Остальное, если
Effective-MaximumPasswordAge = 0x8000000000000000
, затемTO!msDS-UserPasswordExpiryTimeComputed = 0x7FFFFFFFFFFFFFFF
(гдеEffective-MaximumPasswordAge
определяется в разделе [MS-SAMR] 3.1.1.5).В противном случае,
TO!msDS-UserPasswordExpiryTimeComputed = TO!pwdLastSet + Effective-MaximumPasswordAge
(гдеEffective-MaximumPasswordAge
определяется в разделе [MS-SAMR] 3.1.1.5).
Итак, есть как минимум два магических значения для msDS-UserPasswordExpiryTimeComputed
: 0x7FFFFFFFFFFFFFFF
, а также 0
, Похоже, что они оба представляют немного разные значения "никогда" (пароль никогда не был установлен, пароль учетной записи установлен никогда не истекает, максимальный срок действия пароля не существует). Я предполагаю, что запрашиваемые вами аккаунты попадают в одну из перечисленных выше категорий. Мне было бы любопытно, что необработанные значения msDS-UserPasswordExpiryTimeComputed
поля есть.
Если вы недавно создали политику ограничения срока действия паролей, мне интересно, может быть, вам придется заставлять пользователей сбрасывать свои пароли, чтобы они вступили в силу? Я думал, что поведение каждого пароля истекает немедленно, но прошло много лет с тех пор, как нужно было думать об управлении политикой устаревания паролей.
Вот сценарий, который запускается в определенном OU и получает имя пользователя, адрес электронной почты, dn, последний установленный пароль, вычисленный срок действия и количество дней, в течение которых пароль истечет.
Пропускает всех пользователей, для которых включена функция «Пропуск без ограничения срока действия».
Также пропускает пользователей с ограниченными возможностями.
Это можно улучшить с помощью логики, упомянутой в спецификациях msDS-UserPasswordExpiryTimeComputed (подробности см. в других ответах).
Get-ADUser -SearchBase "OU=Users,DC=domain,DC=org" `
-filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} `
–Properties "SamAccountName","mail","distinguishedName","pwdLastSet","msDS-UserPasswordExpiryTimeComputed","msDS-UserPasswordExpiryTimeComputed" |
Select-Object -Property "SamAccountName","mail","distinguishedName",
@{Name="Password Last Set"; Expression={[datetime]::FromFileTime($_."pwdLastSet")}},
@{Name="Password Expiry Date"; Expression={[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")}},
@{Name="Password Expired"; Expression=`
{
if(([datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed") - (GET-DATE)).Days -le 0)
{
if([datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed").Year -eq 1600)
{
'Password Never Set'
}
else
{
'Yes'
}
}
else
{
'No'
}
}
} |
Export-CSV "C:\temp\PasswordExpirationReport.csv" -NoTypeInformation -Encoding UTF8