如何用PSCustomObject引用GPO导出XML中的AD组名称子项?
问题描述
我有一个从WinServer 2019导出的GPO XML文件,想要提取其中包含AD组名称的子项。初始XML片段如下:
<q1:UserRightsAssignment> <q1:Name>SeNetworkLogonRight</q1:Name> <q1:Member> <SID xmlns="http://www.microsoft.com/GroupPolicy/Types">S-1-5-9</SID> <Name xmlns="http://www.microsoft.com/GroupPolicy/Types">NT AUTHORITY\ENTERPRISE DOMAIN CONTROLLERS</Name> </q1:Member>
我尝试使用以下PowerShell命令:
[xml]$GpoXml = Get-GPOReport -name $param1 -ReportType Xml $Object3 = foreach ($p in $GpoXml.GPO.Computer.ExtensionData.Extension.UserRightsAssignment) { if ($p.Name -ne $null) { [PSCustomObject]@{ "Name" = $p.Name "Value" = $p.Member.Name } } }
其中$p.Name能正确获取到SeNetworkLogonRight,但$p.Member.Name返回的是System.Object[]。请问这是什么原因?该如何正确引用Member/Name子项的值?
更新后的完整XML块:
<q1:UserRightsAssignment> <q1:Name>SeNetworkLogonRight</q1:Name> <q1:Member> <SID xmlns="http://www.microsoft.com/GroupPolicy/Types">S-1-5-9</SID> <Name xmlns="http://www.microsoft.com/GroupPolicy/Types">NT AUTHORITY\ENTERPRISE DOMAIN CONTROLLERS</Name> </q1:Member> <q1:Member> <SID xmlns="http://www.microsoft.com/GroupPolicy/Types">S-1-5-11</SID> <Name xmlns="http://www.microsoft.com/GroupPolicy/Types">NT AUTHORITY\Authenticated Users</Name> </q1:Member> <q1:Member> <SID xmlns="http://www.microsoft.com/GroupPolicy/Types">S-1-5-32-544</SID> <Name xmlns="http://www.microsoft.com/GroupPolicy/Types">BUILTIN\Administrators</Name> </q1:Member> <q1:Member> <Name xmlns="http://www.microsoft.com/GroupPolicy/Types">Admin</Name> </q1:Member> </q1:UserRightsAssignment>
原因分析
当XML中存在多个同名的<q1:Member>节点时,PowerShell会将$p.Member解析为对象数组,而非单个对象。此时直接访问$p.Member.Name,本质是调用数组的Name属性,PowerShell会返回数组类型标识System.Object[],而非具体的名称值。
解决方法
需要针对$p.Member的数组特性处理,可根据需求选择以下两种方式:
方式1:合并所有组名为单个字符串
如果希望在Value字段中用逗号分隔展示所有AD组名称:
[xml]$GpoXml = Get-GPOReport -name $param1 -ReportType Xml $Object3 = foreach ($p in $GpoXml.GPO.Computer.ExtensionData.Extension.UserRightsAssignment) { if ($p.Name -ne $null) { [PSCustomObject]@{ "Name" = $p.Name "Value" = ($p.Member.Name -join ', ') } } }
方式2:为每个组名生成独立记录
如果希望每个AD组名称对应一条单独的对象记录,可嵌套循环遍历$p.Member:
[xml]$GpoXml = Get-GPOReport -name $param1 -ReportType Xml $Object3 = foreach ($p in $GpoXml.GPO.Computer.ExtensionData.Extension.UserRightsAssignment) { if ($p.Name -ne $null) { foreach ($member in $p.Member) { [PSCustomObject]@{ "RightName" = $p.Name "GroupName" = $member.Name } } } }
额外注意
- 部分
Member节点可能没有SID字段(如示例中的Admin),但不影响Name属性的提取。 - 若不确定
$p.Member是单个对象还是数组,可通过$p.Member.GetType().Name判断类型,提升代码兼容性。
内容的提问来源于stack exchange,提问作者szaboors
相关产品推荐
相关产品推荐

