PowerShell构建XML脚本优化:实现单用户多角色合并输出
解决PowerShell生成XML时单用户多角色重复节点问题
核心思路
先将用户数据按用户名分组,把同一用户的所有角色聚合到一起,再为每个用户创建单个<account>节点,在<attribute>(对应Role属性)下添加多个<attributeValues>条目。
修改步骤
1. 数据分组处理
假设你的原始数据是类似这样的对象集合(比如从AD或CSV读取的):
# 示例原始数据 $userRoles = @( [PSCustomObject]@{ Username = 'Fred'; Role = 'Operator' }, [PSCustomObject]@{ Username = 'Fred'; Role = 'Admin' }, [PSCustomObject]@{ Username = 'Alice'; Role = 'Viewer' } )
先按用户名分组,聚合同一用户的所有角色:
$groupedUsers = $userRoles | Group-Object -Property Username
2. 构建目标XML结构
接下来创建XML文档,并为每个分组用户生成单个<account>节点,同时将所有角色作为<attributeValues>添加到Role属性下:
# 初始化XML文档 $xml = New-Object System.Xml.XmlDocument $root = $xml.CreateElement('accounts') $xml.AppendChild($root) | Out-Null foreach ($group in $groupedUsers) { # 创建account节点 $accountNode = $xml.CreateElement('account') $accountNode.SetAttribute('name', $group.Name) # 设置用户名属性 # 创建Role对应的attribute节点 $roleAttribute = $xml.CreateElement('attribute') $roleAttribute.SetAttribute('name', 'Role') # 为每个角色添加attributeValues节点 foreach ($role in $group.Group.Role) { $valueNode = $xml.CreateElement('attributeValues') $valueNode.InnerText = $role $roleAttribute.AppendChild($valueNode) | Out-Null } # 将attribute节点加入account节点,再加入根节点 $accountNode.AppendChild($roleAttribute) | Out-Null $root.AppendChild($accountNode) | Out-Null } # 输出格式化后的XML $xml.InnerXml | Format-Xml # 若没有Format-Xml,可使用 $xml.Save([Console]::Out)
3. 输出效果对比
修改前(错误输出):
<accounts> <account name="Fred"> <attribute name="Role"> <attributeValues>Operator</attributeValues> </attribute> </account> <account name="Fred"> <attribute name="Role"> <attributeValues>Admin</attributeValues> </attribute> </account> <account name="Alice"> <attribute name="Role"> <attributeValues>Viewer</attributeValues> </attribute> </account> </accounts>
修改后(正确输出):
<accounts> <account name="Fred"> <attribute name="Role"> <attributeValues>Operator</attributeValues> <attributeValues>Admin</attributeValues> </attribute> </account> <account name="Alice"> <attribute name="Role"> <attributeValues>Viewer</attributeValues> </attribute> </account> </accounts>
适配现有脚本的注意事项
- 如果你的原始脚本是从数据源(如CSV、数据库)直接循环生成节点,替换成先分组再循环分组后的结果即可。
- 若需要保留其他用户属性(如邮箱、部门),在分组时确保这些属性在同一用户下是一致的,或者在分组后取第一个用户的属性值(假设同一用户的其他属性无差异)。
内容的提问来源于stack exchange,提问作者surge3333
相关产品推荐
相关产品推荐

