powershellpscustomobject

How to create a reference to a child item in XML using PSCustomObject


I have a XML file, generated by WinServer 2019 (GPO export). I'd like to create a reference to a child item, to the one, which contains the name of the AD groups:

        <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>

The command, I tried:

[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
        }
    }
}

For the $p.$Name I got "SeNetworkLogonRight" as Name, but for the Value I got "System.Object[]" answer. Why is that? How should I create a reference to get the value of the Member/Name item?

Many thanks!

Update:

The full block:

> <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>

Solution

  • You have multiple <Member> child elements, which causes PowerShell to return them as an array (of type [object[] (System.Object[]).

    Accessing the .Name property on this array - due to PowerShell's member-access enumeration - then returns the array of <Name> grandchild elements, across all <Member> elements.

    Also note that you must access the .InnerText property of .Name in order to get only the element's text in this case (because the element also has attributes).

    You need to:

    $Object3 = foreach ($p in $GpoXml.GPO.Computer.ExtensionData.Extension.UserRightsAssignment) {
        if ($p.Name) {
          foreach ($m in $p.Member) {
            [PSCustomObject]@{
                Name = $p.Name
                Value = $m.Name.InnerText
            }
          }
        }
    }
    
    $Object3 = foreach ($p in $GpoXml.GPO.Computer.ExtensionData.Extension.UserRightsAssignment) {
        if ($p.Name) {
            [PSCustomObject]@{
                Name = $p.Name
                Value = $p.Member.Name.InnerText -join '/'
            }
        }
    }