I create a custom object
$ToExport = [pscustomobject]@{
"samAccountName" = ''
"forwarded" = @{
"ForwardTo" = ""
"RedirectTo" = ""
"Enabled" = ""
"Description" = ""
}
}
The i parse through mailboxes and their forwarding rules, fill the properties and try to put the object into an array:
$Testarray = @()
foreach($m in $mbx){
$ToExport.samAccountName = $m.SamAccountName
$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
}
$ToExport.forwarded.ForwardTo = $null
$ToExport.forwarded.RedirectTo = $null
$ToExport.forwarded.Enabled = $null
$ToExport.forwarded.Description = $null
}
The Problem is when i then check the content of the array all Objects in it have the same samAccountName and when i ope forwarded all properties in there are empty. I dont see where i either overwrite the name of all existing array objects or delete the content under the object: forwarded
$Testarray
samAccountName forwarded
-------------- ---------
Name1 {RedirectTo, ForwardTo, Description, Enabled}
Name1 {RedirectTo, ForwardTo, Description, Enabled}
Name1 {RedirectTo, ForwardTo, Description, Enabled}
Name1 {RedirectTo, ForwardTo, Description, Enabled}
$Testarray[0].forwarded
Name Value
---- -----
RedirectTo
ForwardTo
Description
Enabled
I want to put it all into one array so i can later on export it as a json or xml file.
When $ToExport
is a reference-type object and you do:
$Testarray += $ToExport
What you're really doing is adding a reference to $ToExport
to $TestArray
, not a copy of it.
So when you then subsequently update property values on $ToExport
or one of it's members (like forwarded
), it's reflected by all references to said object.
You've essentially added the same object to the array 4 times, overwriting the property values every time.
Instead, create a new [ordered]
dictionary on each loop iteration - when you subsequently convert the hashtable to a custom object, PowerShell will copy the properties to a new, distinct object, and you'll no longer see the behavior observed:
$Testarray = @()
foreach($m in $mbx){
$forwarded = [ordered]@{
'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){
$forwarded.ForwardTo += $r.ForwardTo}
if($r.RedirectTo -like "*smtp*" -and ($AcceptedDomains | %{"$($r.RedirectTo)" -like "*$_*"}) -notcontains $true){
$forwarded['RedirectTo'] += $r.RedirectTo}
$forwarded['Description'] += $r.Description
$forwarded['Enabled'] += $r.Enabled
}
}
Write-Host($m.samAccountName)
if($forwarded['ForwardTo'].Length -or $forwarded['RedirectTo'].Length){
# create new object
$Testarray += [pscustomobject]@{
'samAccountName' = $m.SamAccountName
# convert ordered hashtable to object
'forwarded' = [pscustomobject]$forwarded
}
}
# no need to clean object template, it'll get recreated
}
If your goal is to export the list of forwarding rules to a flat format (like CSV), then I'd suggest attaching the SAMAccountName value to each rule, and then export those:
$testArray = foreach($m in $mbx){
Get-InboxRule -Mailbox $m.SamAccountName |Where-Object {
$r = $_
($r.ForwardTo -like "*smtp*" -and ($AcceptedDomains | %{"$($r.ForwardTo)" -like "*$_*"}) -notcontains $true) -or
$r.RedirectTo -like "*smtp*" -and ($AcceptedDomains | %{"$($r.RedirectTo)" -like "*$_*"}) -notcontains $true
} |Select -Property @{Name='SamAccountName';Expression={$m.SamAccountName}} RedirectTo,ForwardTo,Description,Enabled
}
$testArray |Export-Csv path\to\forward_rules_export.csv -NoTypeInformation
Piping to Select-Object -Property
will also cause the creation of a new, distinct object instance, once again preempting the problematic behavior you describe.