Adding together duplicate values in an array

Hello Powershell.org. I have been searching google all day for an answer to this and I am just not getting what I need so hopefully somebody here can offer some assistance. The short explanation is that I have 2 arrays that each contain some duplicate info. See below

$ObjColl

Name       TotalUsers TotalInbox
----                ----------        ----------
IT                         3               3
Accounting        4               2
Marketing          2               1

And the second one…

$ObjColl1

Name       TotalUsers TotalInbox
----               ----------          ----------
Accounting       2                1         
Marketing         2                1         

So when I add them together:

$Final += $Objcoll
$Final += $Objcoll1

I get the following output:

$Final

Name       TotalUsers TotalInbox
----                 ----------        ----------
IT                          3                3
Accounting         4                2
Marketing           2                1
Accounting         2                1
Marketing           2                1

What I actually want to do is aggregate the totals rather than doing a literal “combining” of the arrays. How can this be accomplished? Example of desired output below:

$Final

Name       TotalUsers TotalInbox
----                  ----------       ----------
IT                          3                3
Accounting         6                3
Marketing           4                2

Thanks in advance for any assistance!

Try this and see if it works:

https://gist.github.com/anonymous/e3070d089fb17392de2bc86db7ed529e

Hi L-Bo,

By the looks of it you have two Objects stored in two different variables. Your Objects have three properties - Name, TotalUsers and TotalInbox.

Here is an example that you can take and re-work to suit your needs.

$x = [PscustomObject]@{
Numbers = 1
AnotherNumber = 5
}

$y = [PsCustomObject]@{
Numbers = 2
AnotherNumber = 5
}

$b = [PsCustomObject]@{
Numbers = ($x.Numbers + $y.numbers)
AnotherNumber = ($x.AnotherNumber + $y.AnotherNumber)

}

This is a very basic example of how you can create your own object with information from the properties of other objects. Let us know how you go with your scripting!

Thank you both for the prompt response. I tried the suggestion that KonfigurationKing suggested though I didn’t think it would work for me. I ended up changing the pscustomobject I had into a hashtable object, but still with duplicate values. I have yet to try Flynn’s suggestion, but in reading it I can see the concept and I think that is what I am looking for. I will let you know how it works for me, the help is much appreciated!

Not sure how you got two posts in here. Look at the other for a dynamic example.

Because I’m bored.

$one = 'IT','Accounting','Marketing' | % {

[pscustomobject]@{

name = $_
totalusers = (1..9) |Get-Random
totalinbox = (1..9) |Get-Random

}

}


$two = 'IT','Accounting','Marketing' | % {

[pscustomobject]@{

name = $_
totalusers = (1..9) |Get-Random
totalinbox = (1..9) |Get-Random


}

}


$points = $one + $two | group name | %{

$n = $_.name
$group = $total | ? {$_.name -eq $n}

[pscustomobject]@{

name = $n
totalusers = ($group.totalusers | Measure-Object -Sum).sum
totalinbox = ($group.totalinbox | Measure-Object -Sum).sum


}

}


[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms.DataVisualization")
$chart1 = New-object System.Windows.Forms.DataVisualization.Charting.Chart
$chart1.Width = 800
$chart1.Height = 150
$chart1.BackColor = [System.Drawing.Color]::White
[void]$chart1.Titles.Add("Total Users")
$chart1.Titles[0].Font = "segoeuilight,10pt"
$chart1.Titles[0].Alignment = "topLeft"
$chartarea = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea
$chartarea.Name = "ChartArea1"
$chart1.ChartAreas.Add($chartarea)
[void]$chart1.Series.Add("data1")
$chart1.Series["data1"].ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::Bar
$chart1.Series["data1"].CustomProperties = 'BarLabelStyle=Outside,DrawingStyle=Emboss'
$chart1.Series["data1"].Palette = 'BrightPastel'
$x = $points.name
$y = $points.totalusers
$chart1.Series["data1"].Points.DataBindXY([string[]]$x, [int[]]$y)
$chart1.ChartAreas.AxisX.MajorGrid.Enabled = $false
$chart1.ChartAreas.AxisY.MajorGrid.Enabled = $false
$chart1.SaveImage("chart.png", "png")

chart.png

Flynn,

You have to account for duplicates. Array could contain one or more of the same therefore you group first to get the unique values and then do the math.

Thank you all for the prompt replies and the good ideas to try out! Dan Potter had the suggestion that worked the best for me. The Chart.png was a really fancy touch! You were missing the “start-process” cmdlet in front of it to make it auto launch, but I really like the presentation! I have pasted my full working code below in case anyone is interested, or finds this helpful. I am also open to constructive criticism, if anyone sees any better, more efficient ways to achieve the same results I am welcome to them!

$ADIV = Get-ADOrganizationalUnit -SearchBase 'OU=Adiv,OU=Units,DC=acmecorp,DC=bdiv,DC=com' -Filter *
$BDIV = Get-ADOrganizationalUnit -SearchBase 'OU=Bdiv,OU=HQ,OU=Units,DC=acmecorp,DC=bdiv,DC=com' -Filter * 
$CDIV = Get-ADOrganizationalUnit -SearchBase 'OU=Cdiv,OU=New,OU=Units,DC=acmecorp,DC=bdiv,DC=com' -Filter *

[array]$Objcoll = @()
[array]$Objcoll1 = @()
[array]$Objcoll2 = @()
[array]$Final = @()

ForEach($I in $ADIV.distinguishedname)
{
    $Data = Get-ADUser -Filter * -SearchBase $I -Properties mailnickname,department

    $Props = [ordered]@{
    Unit = (Get-ADOrganizationalUnit -Identity $I).name
    UsersTotal = ($Data | ? {$_.Department -eq 'BDIV'}).count
    InboxesTotal = ($Data | ? {$_.Department -eq 'BDIV' -and $_.MailNickName -ne $null}).count
    }

    $Obj = New-Object -TypeName PSObject -Property $Props

    $Objcoll += $Obj
}

ForEach($I in $BDIV.distinguishedname)
{
    $Data = Get-ADUser -Filter * -SearchBase $I -Properties mailnickname,department

    $Props = [ordered]@{
    Unit = (Get-ADOrganizationalUnit -Identity $I).name
    UsersTotal = ($Data | ? {$_.Department -eq 'BDIV'}).count
    InboxesTotal = ($Data | ? {$_.Department -eq 'BDIV' -and $_.MailNickName -ne $null}).count
    }

    $Obj1 = New-Object -TypeName PSObject -Property $Props

    $Objcoll1 += $Obj1
}

ForEach($I in $CDIV.distinguishedname)
{
    $Data = Get-ADUser -Filter * -SearchBase $I -Properties mailnickname,department

    $Props = [ordered]@{
    Unit = (Get-ADOrganizationalUnit -Identity $I).name
    UsersTotal = ($Data | ? {$_.Department -eq 'BDIV'}).count
    InboxesTotal = ($Data | ? {$_.Department -eq 'BDIV' -and $_.MailNickName -ne $null}).count
    }

    $Obj2 = New-Object -TypeName PSObject -Property $Props

    $Objcoll2 += $Obj2
}

$Objcoll += $Objcoll1
$Objcoll += $Objcoll2

($Objcoll | sort Unit) | %{

$N = $_.Unit
$Group = $Objcoll | ? {$_.Unit -eq $N}

$FObj = [pscustomobject]@{
Unit = $N
UsersTotal = ($Group.UsersTotal | Measure-Object -Sum).sum
InboxesTotal = ($Group.InboxesTotal | Measure-Object -Sum).sum
}

if($Final.Unit -match $Fobj.Unit)
{"Unit already exists in Final report"}
Else
{$Final += $FObj}

}
$Final