Home > Mobile >  How to create a reference to a child item in XML using PSCustomObject
How to create a reference to a child item in XML using PSCustomObject

Time:01-12

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>

CodePudding user response:

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:

  • either: create a [pscsustomobject] instance for each member.
$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
        }
      }
    }
}
  • or: if you want to stick with a single [pscustomobject] per privilege and want a string representation of the array of member names so that you can export the objects to a CSV file, for instance, you'll need to come up with a custom stringification of the array; in this example, / is used as the separator:
$Object3 = foreach ($p in $GpoXml.GPO.Computer.ExtensionData.Extension.UserRightsAssignment) {
    if ($p.Name) {
        [PSCustomObject]@{
            Name = $p.Name
            Value = $p.Member.Name.InnerText -join '/'
        }
    }
}
  • Related