【问题标题】:Get-ADUser password expiration for users in specific OUs特定 OU 中用户的 Get-ADUser 密码过期
【发布时间】:2018-04-10 06:05:46
【问题描述】:

我可以获得单个用户的有效“msDS-UserPasswordExpiryTimeComputed”属性:

(([DateTime]::FromFileTime((Get-ADUser $UserName -Properties "msDS-UserPasswordExpiryTimeComputed")."msDS-UserPasswordExpiryTimeComputed")))

但我无法定位一组特定用户。我较大的脚本旨在从特定 OU 的帐户中提取各种 AD 用户属性并导出到 csv。除“PasswordExpiry”对象外,所有属性均按预期填充。

以下示例为每个用户返回一个虚假的“PasswordExpiry”日期“12/31/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”属性计算过期时间。但我想提取实际值,因为年龄政策可能是未知的。任何帮助表示赞赏。

【问题讨论】:

    标签: powershell foreach select-object


    【解决方案1】:

    除了“*”之外,我还必须定义属性才能使其工作。在这种情况下,显然只有星号是不够的。

    Get-ADUser -Identity "$UserName" -Properties *,"msDS-UserPasswordExpiryTimeComputed"
    

    我认为只有在没有 -SearchBase 的情况下才能工作的第二个例子实际上一直在工作。正如 Bacon Bits 强调的那样,我只查询了一小部分过期设置为从不的用户。所以 null 是一个有效的输出。

    这不是原始脚本的问题。无论如何,它都会返回“12/31/1600”。如上所述,我必须添加附加属性才能获得正确的值。这些现在很好。

    $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”)}}
    

    编辑:现在按照 Bacon Bits 的建议执行此操作:

    $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}
    

    【讨论】:

    • 我会避免使用*。这样做会获取大量数据——尤其是在您使用缩略图照片时——并使您的域控制器做的工作超出了他们的需要。指定您希望使用的准确、完整的属性列表。
    • 我就是这样开始的,然后随着属性列表的增加,为了方便而切换到*。但它造成了我的 PasswordExpiry 问题,让我陷入了混乱。我还将它更改为循环遍历 OU 数组,而不是从文本文件中读取。我觉得它现在在大搜索期间运行得更快。
    【解决方案2】:

    根据the specmsDS-UserPasswordExpiryTimeComputed

    msDS-UserPasswordExpiryTimeComputed 属性存在于 AD DS 但不存在于 AD LDS。

    该属性表示对象的密码到期的时间。让TO 成为在其上读取属性msDS-UserPasswordExpiryTimeComputed 的对象。如果TO 不在域NC 中,则TO!msDS-UserPasswordExpiryTimeComputed = null。否则让D 成为包含TO 的域NC 的根。 DC 按照下面指定的顺序应用以下规则来确定TO!msDS-UserPasswordExpiryTimeComputed 的值:

    • 如果在TO!userAccountControl 中设置了ADS_UF_SMARTCARD_REQUIREDADS_UF_DONT_EXPIRE_PASSWDADS_UF_WORKSTATION_TRUST_ACCOUNTADS_UF_SERVER_TRUST_ACCOUNTADS_UF_INTERDOMAIN_TRUST_ACCOUNT 位中的任何一个,则在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-MaximumPasswordAgeEffective-MaximumPasswordAge 在 [MS-SAMR] 第 3.1.1.5 节中定义)。

    所以,msDS-UserPasswordExpiryTimeComputed 至少有两个魔法值:0x7FFFFFFFFFFFFFFF0。它们似乎都代表了“从不”的略微不同的含义(从未设置过密码,帐户密码设置为永不过期,不存在最大密码使用期限)。我的猜测是您查询的帐户属于上述类别之一。我很好奇msDS-UserPasswordExpiryTimeComputed 字段的原始值是什么。

    如果您最近创建了密码期限政策,我想知道您是否可能需要强制用户重置密码才能使其生效?我认为这种行为是每个人的密码都会立即过期,但我已经多年没有考虑管理密码使用期限政策了。

    【讨论】:

    • 感谢您为我指明正确的方向。一旦我检查了 aduc,我就意识到发生了什么,然后它帮助我找出了最初的问题。
    猜你喜欢
    • 1970-01-01
    • 2020-02-08
    • 2013-04-28
    • 2021-07-23
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多