You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 15:55:14