PowerShell检测Windows锁屏密码脚本结果不稳定及账户锁定报错咨询
解决Windows本地用户密码检测脚本的账户锁定报错问题
问题背景
我编写了一段用于检测Windows系统是否启用锁屏密码的PowerShell脚本,多数情况下结果符合预期,但部分运行时会出现账户锁定相关错误。该脚本集成于Electron应用,在Windows 10和11全版本中均有出现此问题,近期报错频率有所上升。
原脚本代码
Add-Type -AssemblyName System.DirectoryServices.AccountManagement $PrincipalContext = New-Object System.DirectoryServices.AccountManagement.PrincipalContext('Machine') try { Get-LocalUser | Where-Object Enabled -eq $true | ForEach-Object { $localUsers = $_.Name $isPasswordNull = $PrincipalContext.ValidateCredentials($localUsers, $null, [System.DirectoryServices.AccountManagement.ContextOptions]'Negotiate') If($isPasswordNull) { Write-Host "User have no password" break } } Write-Host "All user has password" } catch { Write-Host $Error[0] } finally { $PrincipalContext.Dispose() }
报错信息
Exception calling "ValidateCredentials" with "3" argument(s): "The referenced account is currently locked out and may not be logged on to. "
代码修改建议
1. 过滤已锁定账户(核心修复)
原脚本未排除已锁定的启用用户,调用ValidateCredentials会直接触发锁定账户的报错。修改时先过滤掉LockedOut状态为$false的用户:
Add-Type -AssemblyName System.DirectoryServices.AccountManagement $PrincipalContext = New-Object System.DirectoryServices.AccountManagement.PrincipalContext('Machine') try { # 仅处理启用且未锁定的本地用户 Get-LocalUser | Where-Object { $_.Enabled -eq $true -and $_.LockedOut -eq $false } | ForEach-Object { $localUser = $_.Name $hasEmptyPassword = $PrincipalContext.ValidateCredentials($localUser, $null, [System.DirectoryServices.AccountManagement.ContextOptions]'Negotiate') if ($hasEmptyPassword) { Write-Host "用户 $localUser 未设置密码" return # 找到目标用户后终止检测 } } Write-Host "所有启用且未锁定的用户均已设置密码" } catch { Write-Host "执行出错: $($Error[0].Exception.Message)" } finally { $PrincipalContext.Dispose() }
2. 循环内添加局部错误捕获
为避免单个用户的意外错误导致整个脚本终止,可在循环内添加独立的try/catch块:
Add-Type -AssemblyName System.DirectoryServices.AccountManagement $PrincipalContext = New-Object System.DirectoryServices.AccountManagement.PrincipalContext('Machine') try { Get-LocalUser | Where-Object { $_.Enabled -eq $true -and $_.LockedOut -eq $false } | ForEach-Object { $localUser = $_.Name try { $hasEmptyPassword = $PrincipalContext.ValidateCredentials($localUser, $null, [System.DirectoryServices.AccountManagement.ContextOptions]'Negotiate') if ($hasEmptyPassword) { Write-Host "用户 $localUser 未设置密码" return } } catch { Write-Host "验证用户 $localUser 时出错: $($Error[0].Exception.Message)" continue # 跳过当前用户,继续检测其他用户 } } Write-Host "所有启用且未锁定的用户均已设置密码" } catch { Write-Host "全局执行出错: $($Error[0].Exception.Message)" } finally { $PrincipalContext.Dispose() }
Windows设置调整方案
1. 调整账户锁定策略
若报错频率上升,可能是系统账户锁定阈值过低,多次验证触发锁定。可通过本地组策略调整:
- 按下
Win+R,输入gpedit.msc打开本地组策略编辑器 - 导航到「计算机配置」→「Windows设置」→「安全设置」→「账户策略」→「账户锁定策略」
- 调高「账户锁定阈值」(设为0表示永不锁定),或缩短「账户锁定时间」
2. 排查异常账户锁定原因
打开事件查看器,查看「Windows日志」→「安全」中的事件ID 4740(账户被锁定),定位频繁锁定的账户,排查是否有其他程序在尝试登录该账户,导致锁定后脚本验证触发报错。
内容的提问来源于stack exchange,提问作者NJT
相关产品推荐
相关产品推荐

