PowerShell自定义对象数组异常:属性被覆盖且嵌套哈希表为空
问题原因分析
你遇到的问题核心是对象引用复用导致的:
- 你在循环外部只创建了一个
$ToExport对象实例,每次循环只是修改这个对象的属性,然后将它的引用添加到数组$Testarray中。 - 数组里的所有元素其实都是指向同一个对象的指针,所以最后所有元素的
samAccountName会显示为最后一次循环修改的值,并且你在循环末尾清空属性时,数组里所有对象的属性都会被同步清空。
解决方案
解决办法很直接:在每次邮箱循环内部创建新的$ToExport对象,确保每个邮箱对应独立的对象实例,彻底避免引用复用问题。
修改后的完整代码:
$Testarray = @() foreach($m in $mbx){ # 每次循环都创建全新的PSCustomObject实例 $ToExport = [pscustomobject]@{ "samAccountName" = $m.SamAccountName "forwarded" = @{ "ForwardTo" = "" "RedirectTo" = "" "Enabled" = "" "Description" = "" } } $rule = Get-InboxRule -Mailbox $m.SamAccountName foreach($r in $rule){ if(($r.ForwardTo) -OR ($r.RedirectTo)){ if($r.ForwardTo -like "*smtp*" -and ($AcceptedDomains | %{"$($r.ForwardTo)" -like "*$_*"}) -notcontains $true){ $ToExport.forwarded.ForwardTo += $r.ForwardTo } if($r.RedirectTo -like "*smtp*" -and ($AcceptedDomains | %{"$($r.RedirectTo)" -like "*$_*"}) -notcontains $true){ $ToExport.forwarded.RedirectTo += $r.RedirectTo } $ToExport.forwarded.Description += $r.Description $ToExport.forwarded.enabled += $r.Enabled } } Write-Host $ToExport.samAccountName if($ToExport.forwarded.ForwardTo -ne $null -or $ToExport.forwarded.RedirectTo -ne $null){ $Testarray += $ToExport } # 无需再清空属性,下一次循环会创建全新对象 }
额外优化建议
- 替换数组
+=操作:PowerShell原生数组是固定大小的,+=会每次创建新数组,数据量大时性能损耗明显,建议用泛型集合替代:
# 初始化泛型集合 $Testarray = [System.Collections.Generic.List[PSObject]]::new() # 添加元素时使用Add方法 $Testarray.Add($ToExport)
- 优化多规则数据存储:如果一个邮箱有多个符合条件的规则,当前直接拼接字符串会导致内容混淆,可将属性初始化为数组来存储多条规则数据:
"forwarded" = @{ "ForwardTo" = @() "RedirectTo" = @() "Enabled" = @() "Description" = @() } # 添加数据时使用Add方法 $ToExport.forwarded.ForwardTo.Add($r.ForwardTo)
内容的提问来源于stack exchange,提问作者Trippin
相关产品推荐
相关产品推荐

