Срок действия пароля 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
Другие вопросы по тегам