Author Posts

May 28, 2016 at 4:39 am

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!

May 28, 2016 at 6:50 am

Try this and see if it works:

May 28, 2016 at 11:19 am

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!

May 29, 2016 at 11:03 pm

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!

May 31, 2016 at 4:29 pm

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

May 31, 2016 at 4:49 pm

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

May 31, 2016 at 4:59 pm

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.

May 31, 2016 at 11:36 pm

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