Windows AD PowerShell(二):组与成员

3297 字
16 分钟
Windows AD PowerShell(二):组与成员

这是 Windows AD PowerShell 学习记录的第二节,主要整理组对象、成员关系、嵌套组及权限不生效时的排查方法。

二、组与成员#

2.1 查询组的基本信息#

Terminal window
# 查询所有组
Get-ADGroup -Filter *
DistinguishedName : CN=QYNET-Admin,OU=Group,OU=Organization,DC=qy,DC=net
GroupCategory : Security
GroupScope : Global
Name : QYNET-Admin
ObjectClass : group
SamAccountName : QYNET-Admin
DistinguishedName : CN=Domain Admins,CN=Users,DC=qy,DC=net
GroupCategory : Security
GroupScope : Global
Name : Domain Admins
ObjectClass : group
SamAccountName : Domain Admins
Terminal window
# 查询单个组
Get-ADGroup -Identity "QYNET-Admin"
DistinguishedName : CN=QYNET-Admin,OU=Group,OU=Organization,DC=qy,DC=net
GroupCategory : Security
GroupScope : Global
Name : QYNET-Admin
ObjectClass : group
SamAccountName : QYNET-Admin
Terminal window
# 按名称进行模糊查询
Get-ADGroup -Filter 'Name -like "*Admin*"'
Name GroupScope GroupCategory SamAccountName
---- ---------- ------------- --------------
QYNET-Admin Global Security QYNET-Admin
Domain Admins Global Security Domain Admins
DHCP Administrators DomainLocal Security DHCP Administrators
Terminal window
# 查询指定 OU 下的组
Get-ADGroup `
-SearchBase "OU=Group,OU=Organization,DC=qy,DC=net" `
-Filter *
DistinguishedName : CN=QYNET-Admin,OU=Group,OU=Organization,DC=qy,DC=net
GroupCategory : Security
GroupScope : Global
Name : QYNET-Admin
SamAccountName : QYNET-Admin
Terminal window
# 只显示常用字段
Get-ADGroup -Filter * |
Select-Object Name,SamAccountName,GroupScope,GroupCategory,DistinguishedName
Name SamAccountName GroupScope GroupCategory DistinguishedName
---- -------------- ---------- ------------- -----------------
QYNET-Admin QYNET-Admin Global Security CN=QYNET-Admin,OU=Group,OU=Organization,DC=qy,DC=net
Domain Admins Domain Admins Global Security CN=Domain Admins,CN=Users,DC=qy,DC=net
Domain Users Domain Users Global Security CN=Domain Users,CN=Users,DC=qy,DC=net

Get-ADGroup 默认会返回组的基本属性。如果需要查看描述、成员或创建时间等额外属性,需要通过 -Properties 指定:

Terminal window
Get-ADGroup -Identity "QYNET-Admin" `
-Properties Description,Members,Created,Modified |
Select-Object Name,Description,GroupScope,GroupCategory,Created,Modified
Name : QYNET-Admin
Description :
GroupScope : Global
GroupCategory : Security
Created : 2026/9/10 10:32:18
Modified : 2026/9/20 09:15:42

上面的时间仅用于展示输出格式,实际结果以域中的对象属性为准。

常见的组属性如下:

属性含义
NameAD 组对象的名称
SamAccountName组的旧式 Windows 名称
DistinguishedName组对象在 AD 中的完整路径
GroupScope组的作用域,例如 Global、DomainLocal、Universal
GroupCategory组的类型,例如 Security 或 Distribution
Members组的直接成员 DN 列表
MemberOf当前组直接加入了哪些组
Description组的用途说明
Created组对象的创建时间
Modified组对象最后一次修改的时间

2.2 理解组作用域与组类型#

GroupScope 与 GroupCategory 是权限排查中的高频字段:

字段取值可以包含的常见成员可以在哪里授权
GroupScopeDomainLocal任意受信任域中的账户和全局组,以及本林中的通用组仅当前组所在域
GroupScopeGlobal同一域中的账户和全局组本林或受信任域中的资源
GroupScopeUniversal本林任意域中的账户、全局组和通用组本林或受信任林中的资源
GroupCategorySecurity安全主体,可以加入 ACL可以用于权限分配,也可以用于邮件分发
GroupCategoryDistribution仅用于逻辑分组或邮件分发不能用于 ACL 权限分配

如果用户已经加入某个组却仍然没有权限,应先检查该组是不是 Distribution 通讯组。通讯组不是安全主体,不参与 ACL 访问判定。

Terminal window
Get-ADGroup -Identity "QYNET-Admin" |
Select-Object Name,GroupScope,GroupCategory
Name GroupScope GroupCategory
---- ---------- -------------
QYNET-Admin Global Security

在多域环境中,通常使用 AGDLP 或 AGUDLP 模型规划权限:

AGDLP :账户(A)→ 全局组(G)→ 域本地组(DL)→ 权限(P)
AGUDLP :账户(A)→ 全局组(G)→ 通用组(U)→ 域本地组(DL)→ 权限(P)

这种方式可以把“人员归属”和“资源权限”分开管理,减少直接向用户账户分配权限的情况。

2.3 创建、修改与删除组#

创建一个全局安全组:

Terminal window
New-ADGroup `
-Name "GG-IT-Admins" `
-SamAccountName "GG-IT-Admins" `
-GroupScope Global `
-GroupCategory Security `
-Path "OU=Group,OU=Organization,DC=qy,DC=net" `
-Description "IT 管理员账户组"

执行成功时默认不返回内容,可以立即查询验证:

Terminal window
Get-ADGroup -Identity "GG-IT-Admins"
DistinguishedName : CN=GG-IT-Admins,OU=Group,OU=Organization,DC=qy,DC=net
GroupCategory : Security
GroupScope : Global
Name : GG-IT-Admins
ObjectClass : group
SamAccountName : GG-IT-Admins

修改组的描述信息:

Terminal window
Set-ADGroup `
-Identity "GG-IT-Admins" `
-Description "用于管理 IT 系统的安全组"

执行成功时默认不返回内容,验证结果如下:

Terminal window
Get-ADGroup -Identity "GG-IT-Admins" -Properties Description |
Select-Object Name,Description
Name Description
---- -----------
GG-IT-Admins 用于管理 IT 系统的安全组

修改组对象的名称:

Terminal window
Get-ADGroup -Identity "GG-IT-Admins" |
Rename-ADObject -NewName "GG-System-Admins"

执行成功时默认不返回内容。再次查询时,CN 已经发生变化:

Terminal window
Get-ADGroup -Identity "GG-IT-Admins" |
Select-Object Name,SamAccountName,DistinguishedName
Name SamAccountName DistinguishedName
---- -------------- -----------------
GG-System-Admins GG-IT-Admins CN=GG-System-Admins,OU=Group,OU=Organization,DC=qy,DC=net

Rename-ADObject 修改的是对象的 CN;如果还需要修改 SamAccountName,应另外使用 Set-ADGroup:

Terminal window
Set-ADGroup -Identity "GG-System-Admins" -SamAccountName "GG-System-Admins"

执行成功时默认不返回内容。可使用以下命令同时验证 CN 与 SamAccountName:

Terminal window
Get-ADGroup -Identity "GG-System-Admins" |
Select-Object Name,SamAccountName
Name SamAccountName
---- --------------
GG-System-Admins GG-System-Admins

删除组属于高风险操作,建议先使用 -WhatIf 确认目标:

Terminal window
Remove-ADGroup -Identity "GG-System-Admins" -WhatIf
What if: Performing the operation "Remove" on target "CN=GG-System-Admins,OU=Group,OU=Organization,DC=qy,DC=net".
Terminal window
# 确认无误后再执行,并保留确认提示
Remove-ADGroup -Identity "GG-System-Admins" -Confirm
Confirm
Are you sure you want to perform this action?
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help: Y
# 输入 Y 后执行删除,成功时不会再返回对象

2.4 查询组成员#

Get-ADGroupMember 默认只返回组的直接成员:

Terminal window
# 查询组的直接成员
Get-ADGroupMember -Identity "QYNET-Admin"
distinguishedName : CN=浅月,OU=User,OU=Admin,OU=Organization,DC=qy,DC=net
name : 浅月
objectClass : user
SamAccountName : qianyue
Terminal window
# 整理常用字段
Get-ADGroupMember -Identity "QYNET-Admin" |
Select-Object Name,SamAccountName,ObjectClass,DistinguishedName
Name SamAccountName ObjectClass DistinguishedName
---- -------------- ----------- -----------------
浅月 qianyue user CN=浅月,OU=User,OU=Admin,OU=Organization,DC=qy,DC=net
Terminal window
# 只查询直接成员中的用户对象
Get-ADGroupMember -Identity "QYNET-Admin" |
Where-Object ObjectClass -eq "user"
distinguishedName : CN=浅月,OU=User,OU=Admin,OU=Organization,DC=qy,DC=net
name : 浅月
objectClass : user
SamAccountName : qianyue

如果组中包含嵌套组,可以使用 -Recursive 继续展开:

Terminal window
Get-ADGroupMember -Identity "QYNET-Admin" -Recursive |
Select-Object Name,SamAccountName,ObjectClass
Name SamAccountName ObjectClass
---- -------------- -----------
浅月 qianyue user

需要注意,-Recursive 返回的是递归展开后的末端成员,不适合用来还原完整的嵌套层级。如果需要检查“哪个组嵌套了哪个组”,仍应先查看直接成员,并逐层查询其中的组对象。

统计组中递归展开后的用户数量:

Terminal window
$members = Get-ADGroupMember -Identity "QYNET-Admin" -Recursive
$members |
Where-Object ObjectClass -eq "user" |
Measure-Object
Count : 1
Average :
Sum :
Maximum :
Minimum :
Property :

2.5 查询用户属于哪些组#

使用 Get-ADPrincipalGroupMembership 查询用户的组成员关系:

Terminal window
Get-ADPrincipalGroupMembership -Identity qianyue |
Select-Object Name,GroupScope,GroupCategory,DistinguishedName
Name GroupScope GroupCategory DistinguishedName
---- ---------- ------------- -----------------
Domain Users Global Security CN=Domain Users,CN=Users,DC=qy,DC=net
QYNET-Admin Global Security CN=QYNET-Admin,OU=Group,OU=Organization,DC=qy,DC=net

只查看安全组:

Terminal window
Get-ADPrincipalGroupMembership -Identity qianyue |
Where-Object GroupCategory -eq "Security" |
Select-Object Name,GroupScope
Name GroupScope
---- ----------
Domain Users Global
QYNET-Admin Global

如果只想查看用户对象 memberOf 属性中记录的直接组成员关系,可以使用:

Terminal window
(Get-ADUser -Identity qianyue -Properties MemberOf).MemberOf |
ForEach-Object { Get-ADGroup -Identity $_ } |
Select-Object Name,GroupScope,GroupCategory
Name GroupScope GroupCategory
---- ---------- -------------
QYNET-Admin Global Security

memberOf 只记录直接成员关系,而且通常不包含用户的主组,例如默认的 Domain Users。排查有效组成员关系时,更适合使用 Get-ADPrincipalGroupMembership,并结合登录会话中的访问令牌进行确认。

2.6 添加与移除组成员#

Terminal window
# 将单个用户加入组
Add-ADGroupMember -Identity "GG-IT-Admins" -Members qianyue
# 执行成功时默认无输出
# 一次加入多个用户
Add-ADGroupMember `
-Identity "GG-IT-Admins" `
-Members user01,user02,user03
# 执行成功时默认无输出
# 将另一个组作为成员加入,实现组嵌套
Add-ADGroupMember `
-Identity "DL-Server-Admins" `
-Members "GG-IT-Admins"
# 执行成功时默认无输出
# 从组中移除用户,并显示确认提示
Remove-ADGroupMember `
-Identity "GG-IT-Admins" `
-Members qianyue `
-Confirm
Confirm
Are you sure you want to perform this action?
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help: Y
# 输入 Y 并成功移除后,默认无输出

输入 Y 并成功移除后,同样不会返回对象。是否没有输出不能单独作为变更成功的证明,应继续运行查询命令验证。

添加完成后应再次查询确认,避免因为名称相似而操作了错误的对象:

Terminal window
Get-ADGroupMember -Identity "GG-IT-Admins" |
Where-Object SamAccountName -eq "qianyue"
distinguishedName : CN=浅月,OU=User,OU=Admin,OU=Organization,DC=qy,DC=net
name : 浅月
objectClass : user
SamAccountName : qianyue
# 如果已经移除,则不会返回任何内容

对高权限组执行成员变更前,可以先解析用户和组的完整 DN:

Terminal window
Get-ADUser -Identity qianyue |
Select-Object Name,SamAccountName,DistinguishedName
Get-ADGroup -Identity "GG-IT-Admins" |
Select-Object Name,SamAccountName,DistinguishedName
Name SamAccountName DistinguishedName
---- -------------- -----------------
浅月 qianyue CN=浅月,OU=User,OU=Admin,OU=Organization,DC=qy,DC=net
Name SamAccountName DistinguishedName
---- -------------- -----------------
GG-IT-Admins GG-IT-Admins CN=GG-IT-Admins,OU=Group,OU=Organization,DC=qy,DC=net

2.7 查询空组与统计成员数量#

查询没有任何直接成员的组:

Terminal window
Get-ADGroup -Filter * -Properties Members |
Where-Object { -not $_.Members } |
Select-Object Name,GroupScope,GroupCategory,DistinguishedName
Name GroupScope GroupCategory DistinguishedName
---- ---------- ------------- -----------------
WSUS Reporters DomainLocal Security CN=WSUS Reporters,CN=Users,DC=qy,DC=net
WSUS Administrators DomainLocal Security CN=WSUS Administrators,CN=Users,DC=qy,DC=net
DHCP Users DomainLocal Security CN=DHCP Users,CN=Users,DC=qy,DC=net

查询每个组的直接成员数量:

Terminal window
Get-ADGroup -Filter * -Properties Members |
Select-Object Name,GroupScope,GroupCategory,
@{Name="DirectMemberCount";Expression={ @($_.Members).Count }} |
Sort-Object DirectMemberCount -Descending
Name GroupScope GroupCategory DirectMemberCount
---- ---------- ------------- -----------------
Exchange Servers Universal Security 2
QYNET-Admin Global Security 1
Organization Management Universal Security 1
WSUS Reporters DomainLocal Security 0

需要注意,Members 属性和上面的统计结果只包含直接成员,不会自动计算嵌套组中的用户。如果对所有组逐一执行递归查询,会对域控制器产生更多查询压力,生产环境中应尽量限制 OU 和组的范围。

2.8 转换组作用域与类型#

使用 Set-ADGroup 可以修改组作用域:

Terminal window
# 将全局组转换为通用组
Set-ADGroup -Identity "GG-IT-Admins" -GroupScope Universal
# 修改组类型
Set-ADGroup -Identity "Mail-IT" -GroupCategory Security

两条命令执行成功时默认不返回内容,可以分别查询验证:

Terminal window
Get-ADGroup -Identity "GG-IT-Admins" |
Select-Object Name,GroupScope,GroupCategory
Get-ADGroup -Identity "Mail-IT" |
Select-Object Name,GroupScope,GroupCategory
Name GroupScope GroupCategory
---- ---------- -------------
GG-IT-Admins Universal Security
Name GroupScope GroupCategory
---- ---------- -------------
Mail-IT Universal Security

组作用域不能任意转换,常见约束如下:

转换方向主要约束
Global → Universal当前全局组不能是另一个全局组的成员
DomainLocal → Universal当前域本地组不能包含其他域本地组,并且成员必须符合通用组的成员规则
Universal → Global成员必须符合全局组规则,即只能包含本域账户和本域全局组,不能包含通用组
Universal → DomainLocal当前通用组不能处于不允许转换的通用组或跨域域本地组嵌套关系中
Global ↔ DomainLocal不能直接互转,需要先转换成 Universal,再转换为目标作用域

早期的 Windows 2000 Mixed 模式不支持 Universal 安全组,也不允许组作用域转换;这不是“林功能级别低于 2003”的限制。现代 AD 环境通常不会再使用该模式,但转换前仍然必须检查成员和嵌套关系。

组类型从 Distribution 改成 Security 后可能立即影响权限判定;从 Security 改成 Distribution 后,ACL 中引用该组的授权将不再生效,因此修改前应先检查使用范围。

2.9 导出组及成员信息#

执行导出前需要确保 C:\Temp 已经存在:

Terminal window
New-Item -Path "C:\Temp" -ItemType Directory -Force
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 2026/9/20 14:30 Temp

如果目录已经存在,-Force 会直接返回现有目录。

将组的基本信息导出为 CSV:

Terminal window
Get-ADGroup -Filter * |
Select-Object Name,SamAccountName,GroupScope,GroupCategory,DistinguishedName |
Export-Csv -Path "C:\Temp\AD-Groups.csv" -NoTypeInformation -Encoding UTF8

Export-Csv 成功时默认不返回内容,可以使用 Get-Item 验证文件:

Terminal window
Get-Item -Path "C:\Temp\AD-Groups.csv" |
Select-Object Name,Length,LastWriteTime
Name Length LastWriteTime
---- ------ -------------
AD-Groups.csv 18264 2026/9/20 14:31:05

导出指定组递归展开后的成员:

Terminal window
Get-ADGroupMember -Identity "QYNET-Admin" -Recursive |
Select-Object Name,SamAccountName,ObjectClass,DistinguishedName |
Export-Csv -Path "C:\Temp\QYNET-Admin-Members.csv" -NoTypeInformation -Encoding UTF8

同样地,成功时不会在控制台输出对象,可以导入文件检查内容:

Terminal window
Import-Csv -Path "C:\Temp\QYNET-Admin-Members.csv"
Name SamAccountName ObjectClass DistinguishedName
---- -------------- ----------- -----------------
浅月 qianyue user CN=浅月,OU=User,OU=Admin,OU=Organization,DC=qy,DC=net

2.10 “已经加入组但仍然没有权限”的排查流程#

当用户已经加入组但仍然无法访问资源时,可以按照以下顺序排查:

  1. 检查目标组的 GroupCategory 是否为 Security。
  2. 检查用户是否是该组的直接成员或递归成员。
  3. 检查嵌套组的作用域和成员规则是否合法。
  4. 检查用户当前登录令牌中是否已经包含该组。
  5. 检查资源 ACL 是否真正向该组授予了权限。
  6. 检查是否存在优先级更高的显式拒绝权限。
  7. 检查域控制器复制是否已经完成。

首先检查组本身:

Terminal window
Get-ADGroup -Identity "QYNET-Admin" |
Select-Object Name,GroupScope,GroupCategory,DistinguishedName
Name GroupScope GroupCategory DistinguishedName
---- ---------- ------------- -----------------
QYNET-Admin Global Security CN=QYNET-Admin,OU=Group,OU=Organization,DC=qy,DC=net

然后检查用户是否位于递归成员列表中:

Terminal window
Get-ADGroupMember -Identity "QYNET-Admin" -Recursive |
Where-Object SamAccountName -eq "qianyue"
distinguishedName : CN=浅月,OU=User,OU=Admin,OU=Organization,DC=qy,DC=net
name : 浅月
objectClass : user
SamAccountName : qianyue

在用户实际登录的计算机上检查当前访问令牌:

Terminal window
whoami /groups
GROUP INFORMATION
-----------------
Group Name Type SID Attributes
====================== ================ ============================================= ==================================================
QYNET\QYNET-Admin Group S-1-5-21-... Mandatory group, Enabled by default, Enabled group
QYNET\Domain Users Group S-1-5-21-...-513 Mandatory group, Enabled by default, Enabled group

组成员关系发生变化后,已经存在的登录会话不会自动获得新的访问令牌。最可靠的验证方式是让用户注销并重新登录;某些 Kerberos 场景也可以执行 klist purge 后重新访问资源,但现有 SMB 会话等连接仍可能继续使用旧状态。

检查文件或目录 ACL:

Terminal window
Get-Acl -Path "\\server\share\folder" |
Select-Object -ExpandProperty Access |
Where-Object IdentityReference -like "*GG-IT-Admins*"
FileSystemRights : Modify, Synchronize
AccessControlType : Allow
IdentityReference : QYNET\GG-IT-Admins
IsInherited : True
InheritanceFlags : ContainerInherit, ObjectInherit
PropagationFlags : None

最后检查 AD 复制状态:

Terminal window
repadmin /replsummary
Source DSA largest delta fails/total %% error
DC01 05m:12s 0 / 5 0
Destination DSA largest delta fails/total %% error
DC01 05m:12s 0 / 5 0

如果不同命令连接到了不同域控制器,也可以使用 -Server 指定同一台 DC 进行对比:

Terminal window
Get-ADGroupMember `
-Identity "QYNET-Admin" `
-Recursive `
-Server "QYNET-CORE01.qy.net"
distinguishedName : CN=浅月,OU=User,OU=Admin,OU=Organization,DC=qy,DC=net
name : 浅月
objectClass : user
SamAccountName : qianyue

排查权限问题时,需要同时区分三件事:AD 中保存的组成员关系、用户登录时生成的访问令牌,以及目标资源上的实际 ACL。只确认其中一项,并不能证明权限已经完整生效。


上一篇:Windows AD PowerShell(一):用户与账户

下一篇:Windows AD PowerShell(三):计算机

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!

打赏
Windows AD PowerShell(二):组与成员
https://springtsuki.xucjno.com/posts/springtsuki/notes/windowsad/powershell/915-group/
作者
SpringTsuki
发布于
2026-09-15
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
SpringTsuki
你好,我是浅月。
公告
浅月的开发小窝!欢迎你来到这里!
音乐
封面

音乐

暂未播放

0:000:00
暂无歌词
分类
标签
站点统计
文章
56
分类
9
标签
42
总字数
188,888
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
GitHub Actions
博客版本
Firefly v6.13.5
文章许可
CC BY-NC-SA 4.0

文章目录