Windows服务器如何创建用户并设置远程登录权限?

多人共用一台 Windows 服务器时,最省事也最危险的做法就是所有人用同一个 Administrator,密码用微信传来传去。出问题时查不到是谁改的,有人离职了还得改一次全公司的密码。正确的做法是每个人一个账户、按职责分组、日常用普通账户加 UAC 提权。

这篇覆盖账户管理的完整链路:图形工具和 PowerShell 两种创建方式、密码策略怎么配才既安全又不折磨人、怎么才能真正让一个普通用户连上远程桌面(这里有 Windows Server 特有的授权陷阱)、远程桌面会话主机场景下的额外配置,最后是禁用默认账户、锁定策略和审计这些收尾工作。

图形方式:lusrmgr.msc 与计算机管理

最快打开本地用户和组管理器的命令:

lusrmgr.msc           :: 本地用户和组
compmgmt.msc          :: 计算机管理,左侧展开"本地用户和组"
mmc                   :: 空的控制台,可自行添加多个管理单元
secpol.msc            :: 本地安全策略(密码策略、用户权限分配在这里)
gpedit.msc            :: 本地组策略编辑器
wf.msc                :: 高级安全防火墙
eventvwr.msc          :: 事件查看器

注意:lusrmgr.msc 在域控制器上不可用(DC 上没有本地账户库,要用 dsa.msc Active Directory 用户和计算机)。另外 Windows Server Essentials 等少数版本中,本地用户和组管理器也有限制。

创建流程很简单:右键"用户" → 新用户 → 填用户名、全名、描述、密码 → 勾选选项 → 创建。四个复选框的含义要看清楚:

选项 说明 建议
用户下次登录时须更改密码 首次登录强制改密 给别人建账户时勾选,管理员知道初始密码
用户不能更改密码 密码被固定 只在服务账户/共享账户场景用,极少用
密码永不过期 绕过密码最长使用期限 服务账户可用;普通人不勾
账户已禁用 创建后即不可用 建备用账户时可以这样留着,用时再启用

建完之后右键用户 → 属性 → "隶属于"页签添加组。这一步决定了这个用户能干什么。

PowerShell 方式:适合脚本化和 Server Core

Server Core 没有图形界面,批量创建账户也只能靠命令行。Microsoft.PowerShell.LocalAccounts 模块在 Server 2016 之后内置。

# 查看现有本地账户
Get-LocalUser | Select-Object Name, Enabled, LastLogon, PasswordExpires, Description | Format-Table -AutoSize
Get-LocalGroup | Select-Object Name, Description

# 创建用户(交互式输入密码,不会出现在命令历史里)
$pwd = Read-Host "请输入 zhangsan 的初始密码" -AsSecureString
New-LocalUser -Name "zhangsan" -Password $pwd -FullName "张三" -Description "运维-外部驻场"

# 脚本化场景(注意:密码会以明文出现在脚本中,仅用于自动化部署且脚本要严格控权)
$pwd = ConvertTo-SecureString "Init@Pwd2024!" -AsPlainText -Force
New-LocalUser -Name "lisi" -Password $pwd -FullName "李四" -Description "开发" -PasswordNeverExpires:$false

# 修改属性
Set-LocalUser -Name "zhangsan" -Description "运维-2024入职"
Set-LocalUser -Name "zhangsan" -PasswordNeverExpires $false
Enable-LocalUser  -Name "zhangsan"
Disable-LocalUser -Name "zhangsan"

# 删除(不可逆,确认真不用了再删)
Remove-LocalUser -Name "lisi"

风险提示:ConvertTo-SecureString ... -AsPlainText 会把密码暴露在脚本文件和命令行历史里。生产环境优先用 Read-Host -AsSecureString 交互式录入,或者从受控的密码库里读取。删除账户是不可逆的,用户配置文件、EFS 加密文件、个人证书也会一并失效,删除前先确认。

组的增删查:

Get-LocalGroupMember -Group "Remote Desktop Users"
Get-LocalGroupMember -Group "Administrators"

Add-LocalGroupMember -Group "Remote Desktop Users" -Member "zhangsan"
Remove-LocalGroupMember -Group "Remote Desktop Users" -Member "zhangsan"

# 域环境:添加域用户到本机远程桌面组
Add-LocalGroupMember -Group "Remote Desktop Users" -Member "CONTOSO\zhangsan"

CMD 时代的命令也还能用,尤其在批处理里:

net user zhangsan Init@Pwd2024! /add /fullname:"张三" /comment:"运维"
net localgroup "Remote Desktop Users" zhangsan /add
net localgroup "Administrators" zhangsan /add
net user                              :: 列出所有本地用户
net user zhangsan                     :: 查看某个用户详情
net localgroup "Remote Desktop Users" :: 查看组成员
net user zhangsan /delete

注意:net user 的密码会明文出现在命令行里,也可能被命令历史记录到脚本中。中文系统的组名要写 "Remote Desktop Users",英文系统同名原文;如果拿不准系统语言,建议直接用 PowerShell 命令,它内部按 SID 处理,不受语言影响。

密码策略:安全与可用性的平衡

密码策略在本地安全策略里配:secpol.msc → 账户策略 → 密码策略。

策略项 建议值 说明
密码必须符合复杂性要求 已启用 大小写 + 数字 + 符号三类中选三类
密码长度最小值 12 个字符 8 位太短,14 位以上会让用户怨声载道
密码最长使用期限 90 天 服务账户可作例外
密码最短使用期限 1 天 防止改回去旧密码
强制密码历史 记住 5 个 防止来回用同一个密码
用可还原的加密来存储密码 已禁用 这个几乎等于明文存储,永远不要开
:: 导出当前安全策略做备份
secedit /export /cfg C:\backup\secpol-$(Get-Date -Format yyyyMMdd).inf

:: 应用新的安全策略模板
secedit /configure /db secedit.sdb /cfg C:\backup\newpolicy.inf /areas SECURITYPOLICY

:: 刷新组策略
gpupdate /force
gpresult /r | findstr /i "密码"

提示:域环境下密码策略由域级别的默认域策略统一控制,本地策略会被覆盖。域内的精细密码策略要用"密码设置容器(PSC)"下的细粒度密码策略来做。

账户锁定策略同样重要,它决定了暴力破解的难度:

策略项 建议值 说明
账户锁定阈值 5 次无效登录 太高等于敞开大门,太低易被反制成拒绝服务
账户锁定时间 30 分钟 超过后自动解锁;设为 0 表示需管理员手工解锁
复位账户锁定计数器 30 分钟 与锁定时间一致即可
# 查看某账户是否被锁定及最后登录情况
Get-LocalUser -Name "zhangsan" | Select-Object Name, Enabled, LastLogon, PasswordLastSet
net user zhangsan | findstr /i "锁定 上次登录"

# 手工解锁(域环境用 net user zhangsan /active:yes)
net user zhangsan /active:yes

让用户真正能远程桌面登录

这是 Windows Server 上最容易踩坑的部分。很多人以为把用户加进 Remote Desktop Users 组就完事了,但在域环境或安装了远程桌面会话主机角色的情况下,光加组是不够的,还必须有"允许通过远程桌面服务登录"这项用户权利。

完整的检查清单:

# 1. 确认用户已启用且密码正常
Get-LocalUser -Name "zhangsan" | Select-Object Name, Enabled, PasswordExpires

# 2. 确认在 Remote Desktop Users 组里
Get-LocalGroupMember -Group "Remote Desktop Users"

# 3. 确认"允许通过远程桌面服务登录"用户权利(需要 secedit 导出查看)
secedit /export /cfg C:\tmp\sec.inf /areas USER_RIGHTS
Select-String -Path C:\tmp\sec.inf -Pattern "SeRemoteInteractiveLogonRight|SeDenyRemoteInteractiveLogonRight"

# 4. 确认远程桌面已开启
Get-ItemProperty 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -Name fDenyTSConnections

SeDenyRemoteInteractiveLogonRight(拒绝通过远程桌面服务登录)与允许项冲突时,拒绝优先。某个用户明明加了组却登录不了,八成是这里被设了拒绝。

用户权利分配的图形路径:

secpol.msc → 本地策略 → 用户权利指派
→ 允许通过远程桌面服务登录       (SeRemoteInteractiveLogonRight)
→ 拒绝通过远程桌面服务登录       (SeDenyRemoteInteractiveLogonRight)
→ 作为服务登录                  (SeServiceLogonRight,服务账户需要)
→ 允许本地登录                  (SeInteractiveLogonRight)
场景 需要满足的条件
工作组单机服务器 加入 Remote Desktop Users 组即可(系统已默认给该组开通了对应权限)
域成员服务器 + 域账户登录 加入本机/Builtin 的 Remote Desktop Users,并确认域策略没有在用户权利里做拒绝
安装了 RD 会话主机角色 还要配置"远程桌面授权"角色并导入 CAL,否则宽限期过后拒绝新连接
多用户同时使用 默认只有两个管理员会话;多人使用需要装 RDS 角色并配置授权 CAL
# 查看是否为会话主机场景
Get-WindowsFeature RDS-RD-Server | Select-Object Installed
query termserver

提示:如果只是两三个管理员做管理用途,千万别安装"远程桌面会话主机"角色。装了之后系统会进入约 120 天的授权宽限期,过期后将拒绝新连接。保持默认的"管理远程桌面"模式就够了。

管理员 vs 普通用户:最佳实践

账户体系的设计原则很简单,能落地更重要:

  • 每人一个账户,禁止共享。出问题要能查到是谁。
  • 日常用普通账户,需要时用 UAC 提权。管理员账户只在进行安装、配置变更时通过 UAC 或 runas 使用。
  • 内置 Administrator 改名并禁用。它是固定 SID(S-1-5-21-...-500),永远存在且不会被锁定策略有效约束。
# 重命名内置管理员(改名不能掩盖 SID,但能增加定向爆破难度)
Rename-LocalUser -Name "Administrator" -NewName "svc-admin-do-not-use"
Disable-LocalUser -Name "svc-admin-do-not-use"

# 确认 Guest 账户状态,默认应长期保持禁用
Get-LocalUser -Name "Guest" | Select-Object Name, Enabled
Disable-LocalUser -Name "Guest"

提权运行单条命令的两种方式:

runas /user:CONTOSO\admin "mmc.exe compmgmt.msc"
runas /user:.\opsadmin "powershell.exe"
# PowerShell 中以其他凭据启动进程
Start-Process powershell -Credential (Get-Credential)
Start-Process mmc -ArgumentList "wf.msc" -Verb RunAs

UAC 相关的组策略(决定管理员能否远程提权):

计算机配置 → Windows 设置 → 安全设置 → 本地策略 → 安全选项
→ 用户帐户控制: 管理员批准模式中管理员的提升提示行为       (设为 提示凭据)
→ 用户帐户控制: 用于内置管理员帐户的管理员批准模式         (启用后内置管理员登录也走 UAC)
→ 用户帐户控制: 远程登录后不准筛选本地账户的管理员令牌     (保持默认禁用)

最后这条要留意。LocalAccountTokenFilterPolicy 注册表项默认是 0(禁用),此时远程登录的管理员拿到的是受限令牌,很多需要完整令牌的操作会失败,提示"拒绝访问"。有人为了省事把它改成 1,那等于让远程登录的管理员全程免 UAC 提权,远程桌面会话里的所有进程都带完整令牌,风险明显上升。保持默认值,遇到权限问题时用 runas 或显式提权,不要关掉它。

审计:出了事要能查出来

审计在默认情况下几乎是空的,需要显式开启。方法如下:

:: 查看当前审计策略
auditpol /get /category:*

:: 开启账户登录事件与账户管理审计(成功和失败都要记)
auditpol /set /subcategory:"登录" /success:enable /failure:enable
auditpol /set /subcategory:"账户管理" /success:enable /failure:enable
auditpol /set /subcategory:"其他登录/注销事件" /success:enable /failure:enable

常用的审计事件 ID:

事件 ID 含义 用途
4624 成功登录 谁在什么时间从哪里登录,注意 Logon Type 字段
4625 登录失败 爆破尝试排查,配合来源 IP 处理
4634 注销 会话结束时间
4720 创建用户 有人偷偷建账户的痕迹
4726 删除用户 同上
4728 / 4732 加入组 权限被提升的关键证据
4740 账户被锁定 配合 4625 找出攻击源

其中 Logon Type 的含义很关键:2 是本地交互式登录,3 是网络登录(访问共享),10 是远程桌面(RemoteInteractive)。查远程桌面登录记录只要筛 LogonType=10。

# 筛选最近的远程桌面登录成功记录(LogonType 10)
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624} -MaxEvents 200 |
  Where-Object { $_.Properties[8].Value -eq 10 } |
  Select-Object TimeCreated, @{n='用户';e={$_.Properties[5].Value}},
                @{n='来源IP';e={$_.Properties[18].Value}} | Format-Table -AutoSize

# 统计登录失败来源 IP Top 10
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625} -MaxEvents 500 |
  ForEach-Object { $_.Properties[19].Value } | Group-Object | Sort-Object Count -Descending |
  Select-Object -First 10 Name, Count

# 日志保留策略要设够大,否则很快被覆盖
wevtutil sl Security /ms:1073741824
wevtutil gl Security

提示:安全日志默认会被循环覆盖,审计开启后务必把日志大小调到足够(生产建议 512 MB 到 1 GB 以上),并考虑转发到集中的日志服务器。攻击者在入侵后第一件事往往是清日志。

常见问题

Q:用户加了 Remote Desktop Users 组,还是提示"登录尝试失败"?
按顺序查:Get-LocalUser 确认账户 Enabled;密码是否过期或初次登录需改密码;SeDenyRemoteInteractiveLogonRight 里有没有默认包含该项;如果装了 RD 会话主机角色,还要检查授权状态是否过期。

Q:提示"用户账户限制阻止了你登录",是怎么回事?
典型情况是密码策略+登录时间+允许登录的工作站三重限制。先用管理员账户登录后查看该账户的"账户"页签属性:登录时间是否受限、允许登录到哪些计算机。

Q:忘记密码怎么办,Administrator 也被锁了?
本地账户密码无法直接找回,只能重置。云服务器优先使用控制台提供的"重置实例密码"功能,它会通过 Agent 完成修改。物理机则可以用安装盘或 PE 离线处理,但这类操作不能加密盘上运行且属于高风险手段,只适合没有其他办法时用。更好的做法是提前保留至少一个备用的本地管理员账户,并把它记在安全的密码库里。

Q:服务用哪个账户跑比较好?
Windows 服务的专用 built-in 账户 NT SERVICE\<服务名> 或 LocalService / NetworkService 优先,只有需要访问网络共享时才用明确指定了具体权限的域账户。永远不要把服务的账户配成管理员。

Q:域环境和单机服务器在用户管理上最大的差别是什么?
账户统一在 AD,需要在域控制器上用 dsa.msc 管理,权限通过域组分发。加到本机 Remote Desktop Users 组时写 域名\用户名。密码策略和锁定策略都由域级 GPO 决定,本机 secpol.msc 里改了也是无效的。

总结

  • 每人一个独立账户,共享 Administrator 是最大的安全与管理隐患;日常用普通账户 + UAC 提权。
  • 创建账户用 New-LocalUser(脚本化)或 lusrmgr.msc(一次性),注意 -AsSecureString 处理密码,不要在脚本里写明文。
  • 让用户能远程桌面登录要同时满足三件事:账户启用、加入 Remote Desktop Users 组、具备 SeRemoteInteractiveLogonRight 且没有被 SeDeny... 拒绝。
  • 多用户并发超过两个管理会话必须装 RDS 角色并配置授权;只做管理用途则不要安装该角色。
  • 内置 Administrator 改名并禁用,Guest 保持禁用;开启登录与账户管理审计,并把安全日志调大到 512 MB 以上。