用户更改密码时,通常是在白天的某个时间。这意味着,如果将密码过期日期设置为上次更改时间 + n 天,则密码会在白天过期。我如何才能强制密码在当天午夜过期?
答案1
我认为如果不手动更改PwdLastSet
ADSI Edit 中的属性,这是不可能的,而且我不建议这样做。
自 1601 年 1 月 1 日凌晨 12:00 以来,该值以 100 纳秒的间隔存储。但是,编辑该属性的唯一选项是将其设置为0
(密码现已过期,用户必须重置),或-1
(PwdLastSet 的值更改为当前日期/时间)。
正如评论中提到的,您需要先将值设置为0
,然后将其设置为-1
。
您可以编写一个脚本,将-1
所有用户的属性更新为某一天的午夜。但是,这会将所有用户的密码设置为在 N 天后的午夜过期(N 是您的域密码策略最大使用期限设置)。这可能会延长密码的最大使用期限。
您将密码设置为午夜过期的目的是什么?
答案2
Windows 根本不支持全局适用的“密码过期时间”概念。您也无法设置时间,只能说它现在已过期,或者刚刚更改。但是,您可以使用命令行 AD 工具或 powershell 编写一个每晚运行的脚本:它可以查询 AD 中密码将在 24 小时内过期的用户(pwdLastSet 比您的密码最大使用期限少一天),并将其设置为 -1(密码已过期)。这样可以避免无意中延长密码有效期,也可以避免中午密码过期。
还有一些第三方工具可以帮你完成这类任务。例如,Hitachi ID 密码管理器的一项功能允许你弹出一个网络浏览器,用户必须在其中更改密码,否则将被注销,你可以将此操作设置为在实际到期前任意天数发生。
答案3
您可以每天午夜运行一个脚本,如果密码设置为第二天过期,则可以强制过期。
有点图解那里
从未在 VBS 中测试过;
Const SEC_IN_DAY = 86400
Const ADS_UF_DONT_EXPIRE_PASSWD = &h10000
Const ADS_SCOPE_SUBTREE = 1000
dim strname
dim strdist
dim dtmvalue
on error resume next
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
objCommand.CommandText = "SELECT distinguishedName, profilepath, name from 'LDAP://dc=Example,dc=com' where objectCategory = 'User'"
Set objuserRecordSet = objCommand.Execute
objUSerRecordSet.MoveFirst
Do Until objuserRecordSet.EOF
strdist = objuserRecordSet.Fields("distinguishedName").Value
strname = objuserRecordSet.Fields("name").Value
Set objUserLDAP = GetObject _
("LDAP://" & strdist)
intCurrentValue = objUserLDAP.Get("userAccountControl")
dtmValue = objUserLDAP.PasswordLastChanged
If intCurrentValue and ADS_UF_DONT_EXPIRE_PASSWD Then
x = "The password does not expire."
Else
Set objDomainNT = GetObject("WinNT://escc.gov.uk")
intMaxPwdAge = objDomainNT.Get("MaxPasswordAge")
If intMaxPwdAge < 0 Then
x = "Password does not expire"
Else
intMaxPwdAge=intMaxPwdAge/86400
strold = ((dtmValue + intMaxPwdAge)-now)
if strold < 2 and strold > 0 then
objUserLDAP.pwdLastSet = 0
objUserLDAP.SetInfo
end if
end if
End If
dtmValue= ""
objuserrecordset.movenext
Loop
或者那里对于 powershell 的示例:
# This PowerShell Script will query Active Directory and return the user accounts with passwords
# set to expire before the end of the next day, export a list of the affected accounts, and require
# a password change at the next logon. The script is configured to ingore accounts which have been
# configured with passwords that never expire, and to ignore accounts who do not have permission to
# change their own password. Any other account would be affected, so be warned before running this
# script, as you could experience unintended consequences. Either modify the script to reduce the
# scope of user accounts, or ensure that accounts that shouldn't be affected are either flaged with
# a non-expiring password or are flagged with "cannot change password. When ready to run/schedule
# in production, remove the -WhatIf from the last line.
#
# - MWT, 10/11/13
# The 89 is based upon your environment. If passwords expire every X (90) days, and you run the script
# in the early morning, you can set it to -1*(X-1) (-89), if you run the script late at night, set it to
# -1*(X-2) (-88).
Import-Module ActiveDirectory # Required for PowerShell 2.0 only
$a = (Get-Date).Date.AddDays(-89)
# The following line will build the variable based upon the noted criteria
$b = Get-ADUser -Property Name,SamAccountName,PasswordLastSet,CannotChangePassword,PasswordNeverExpires -Filter {(PasswordLastSet -lt $a) -and (PasswordNeverExpires -eq $false)} | Where-Object {$_.CannotChangePassword -eq $false}
# The following line will display/export the data logging the accounts to be changed; please note the
# Out-File path and change to suit your needs.
$b | Format-Table Name,PasswordLastSet,CannotChangePassword,PasswordNeverExpires -AutoSize | Out-File -FilePath C:\passwordchanges.txt
# The following line will actually flag the accounts to require a password change (after -WhatIf is removed)
$b.SamAccountName | ForEach-Object {Set-ADUser -Identity $_ -ChangePasswordAtLogon $true -WhatIf}