兄弟们,干弱电这么多年,AD域控这东西,咱们肯定没少碰。尤其是刚入行那会儿,给客户配域环境,动不动就遇到用户登不上、密码改不了、账号莫名其妙被锁这种破事。后来查来查去,发现很多问题都跟一个叫UserAccountControl的属性有关。今天我就用大白话,跟大伙儿好好盘盘这个属性,全是实战里摸爬滚打总结出来的经验。
先说它是个啥。UserAccountControl,简称UAC(别跟Windows那个用户账户控制搞混了),它是AD里每个用户和计算机对象自带的一个属性。你可以把它理解成是个“开关集合体”——里面存了一堆二进制标志位,每个位代表一个账号设置,比如账号是否禁用、密码能不能改、要不要智能卡登录等等。Windows就是靠读这个属性来判断该对账号采取什么操作的。
举个例子,一个正常启用的普通用户账号,它的UAC值是512(十六进制0x200)。要是你把账号禁用了,这值就会变成514。为啥是514?因为禁用标志的值是2,512+2=514,就这么简单。这个属性是累加的,这点特别重要,好多兄弟查账号时就是在这上面栽了跟头。
💡 实际施工经验:有一回给一个工厂做域迁移,新域里批量创建账号后,发现所有用户都没法正常登录。我查了一下UAC值,发现全是512,但用户就是提示“账号被禁用”。后来一查,原来是创建脚本里漏了设置密码永不过期的标志(65536),但密码策略又要求90天改一次,结果密码过期后Windows自动把账号状态改成了“密码过期”(8388608),而8388608+512=8901120,看起来就不是512了。所以查异常账号时,千万别只盯着512,得用位运算或者过滤所有不等于512的账号。
下面这张表是UAC所有标志位的对照,我整理成了段落形式,方便大家对照排查:
- 脚本(1):账号登录时运行登录脚本,一般默认不设。
- 账号禁用(2):这个最常用,账号被禁用了就是这个标志。
- 主文件夹必需(8):要求账号有主文件夹路径。
- 锁定(16):多次输错密码后账号被锁。
- 不需要密码(32):允许空密码账号,安全风险大,生产环境别开。
- 不能更改密码(64):用户自己改不了密码,比如一些服务账号。
- 允许加密文本密码(128):允许明文密码传输,老协议才会用到。
- 临时重复账号(256):跨域信任用的临时账号。
- 普通账号(512):标准用户账号,默认值。
- 域间信任账号(2048):用于域间信任。
- 工作站信任账号(4096):加域的计算机账号。
- 服务器信任账号(8192):域控计算机的账号。
- 密码永不过期(65536):服务账号常用这个,避免密码过期导致服务中断。
- MNS登录账号(131072):多节点网络服务用的。
- 需要智能卡(262144):强制用智能卡登录,安全要求高的环境用。
- 可信委托(524288):允许账号代表其他用户请求服务,比如SQL服务账号。
- 不可委派(1048576):禁止该账号的安全上下文被委派。
- 仅用DES密钥(2097152):老系统兼容用的,现在很少见了。
- 不需要Kerberos预认证(4194304):有些第三方应用需要这个,但有安全风险。
- 密码已过期(8388608):账号密码过期后的状态。
- 信任可认证委派(16777216):高权限委派,敏感设置,别乱开。
- 部分秘密账号(67108864):RODC只读域控用的。
🔧 省钱技巧:很多兄弟做项目时,为了省事,给所有服务账号都设成“密码永不过期”。但客户审计时这往往是个漏洞。我一般建议:对非关键服务账号,用计划任务每90天自动改一次密码,然后重启服务。这样既不用买额外的密码管理软件,又能过审计。脚本里用Set-ADAccountPassword配合Set-ADUser -PasswordNeverExpires $false,比手动改省时省力。
怎么看一个账号的UAC值?最直接的办法是打开AD用户和计算机(ADUC),在用户属性里找到“属性编辑器”选项卡,往下翻就能看到userAccountControl。它显示的是十六进制值,双击编辑时会变成十进制。用PowerShell更简单,一条命令搞定:
get-aduser -identity 用户名 -properties * | select name, useraccountcontrol
想找带某个标志的账号?比如找所有正常账号(512),用这个:
get-aduser -filter * -properties UserAccountControl | where {$_.UserAccountControl -eq 512} | select name, UserAccountControl
要找所有异常账号,就用不等于:
get-aduser -filter * -properties UserAccountControl | where {$_.UserAccountControl -ne 512} | select name, UserAccountControl









最后说说怎么改。在ADUC里直接改属性值就行,比如把禁用账号(514)改成正常(512),就在值框里输入512。用PowerShell更灵活:
set-aduser -identity 用户名 -replace @{useraccountcontrol=512}
或者用专门的Set-ADAccountControl cmdlet,比如关掉“不需要密码”标志:
Set-ADAccountControl -Identity 用户名 -PasswordNotRequired $False
⚠️ 踩过的坑:千万别图省事直接复制网上的PowerShell命令改UAC值。有一次我帮一个客户批量重置账号,用了-replace @{useraccountcontrol=512},结果所有账号的“密码永不过期”标志都被清掉了,第二天一堆服务因为密码过期挂掉。正确做法是先用Get-ADUser读出当前值,然后用位运算-bor或-band来添加或移除标志,比如加“密码永不过期”:$newValue = $currentValue -bor 65536。改之前一定在测试账号上试,别拿生产环境练手。
好了,今天就聊到这儿。UAC这东西看着简单,但用好了能省不少心。下次遇到账号异常,先看看UAC值,八成能定位到问题。兄弟们有遇到什么奇葩的UAC问题,欢迎交流!
