Author Posts

December 20, 2017 at 7:48 pm

Hello. I have an array of objects with three properties as shown below:

PS C:\Windows\system32> $array_objects

User IP Account
—- —– ———
SYSTEM 192.168.137.1 local
SYSTEM 192.168.137.1 local
SYSTEM 192.168.137.2 local
admin 172.16.2.1 domain
admin 172.16.2.1 domain

Some objects have the same User and IP property. I would like to return a unique array of objects based on the User and IP properties and later be able to access all three properties of this array of objects.

I have been able to find the unique array of objects using the Group-Object cmdlet below:

PS C:\Windows\system32> $array_objects = $array_objects | Group-Object -Property "User","IP" | Select -ExpandProperty Name
PS C:\Windows\system32> $array_objects

However, the output of the above command only returns the two grouped properties I cannot access the third property from this new object. I do not want to also group on the third property, I just want to be able to access it like $array_objects[0].Account

Is there another way to find the unique objects based on the User and IP properties, while still being able to access its third property?

December 20, 2017 at 7:55 pm

Would Select-Object -unique help?

Your problem with -ExpandProperty is that -ExpandProperty extracts the contents from whatever one property you specify, and then discards the rest.

-Unique, however, will only identify objects having all three of the same properties – that's not what you want, right?

December 20, 2017 at 8:00 pm

This is similar to a previous post that I responded to. See this post to see if you can leverage that response.
'powershell.org/forums/topic/adding-object-property-array-values-to-individual-csv-cells/#post-89287'

December 20, 2017 at 8:03 pm

$arr = @()
$arr += [PSCustomObject]@{ User='SYSTEM'; IP='192.168.137.1'; Account = 'local' }
$arr += [PSCustomObject]@{ User='SYSTEM'; IP='192.168.137.1'; Account = 'local' }
$arr += [PSCustomObject]@{ User='SYSTEM'; IP='192.168.137.2'; Account = 'local' }
$arr += [PSCustomObject]@{ User='admin'; IP='172.16.2.1'; Account = 'domain' }
$arr += [PSCustomObject]@{ User='admin'; IP='172.16.2.1'; Account = 'domain' }
$arr 

$Groups = $arr | group user,ip 

$Groups | % {
    $PSItem.Name
    $PSItem.Group.Account | select -Unique
}

December 21, 2017 at 4:51 am

Try this, a few ideas based on my previous work.
Stepping through the stages, to see what makes sense and where.

Read the file and display results
(($UserData = Import-Csv -Path .\UserIPObjects.txt -Delimiter ' ') | Group User) | Format-Table -AutoSize

Count Name Group
—– —- —–
3 SYSTEM {@{User=SYSTEM; IP=192.168.137.1; Account=local}...
2 admin {@{User=admin; IP=172.16.2.1; Account=domain}...

Parse the file for unique records adn display results
($UserDataUnique = ForEach($RowItem in ($UserData | Select * -Unique)){$RowItem})

User IP Account
—- — ——-
SYSTEM 192.168.137.1 local
SYSTEM 192.168.137.2 local
admin 172.16.2.1 domain

Consolidate the unique results
($UserDataArray = $UserDataUnique | Select * | Group User)

Count Name Group
—– —- —–
3 SYSTEM {@{User=SYSTEM; IP=192.168.137.1; Account=local}...
2 admin {@{User=admin; IP=172.16.2.1; Account=domain}...

Check User property value
$UserDataArray.Name

SYSTEM
admin

$UserDataArray.Name[0]
SYSTEM

Check IP value
$UserDataArray.Group.IP

192.168.137.1
192.168.137.2
172.16.2.1

$UserDataArray.Group.IP[0]
192.168.137.1

Generate the user IP report
Function Get-UserIPReport
{
ForEach($UserDataRow in $UserDataArray)
{
$UserIPReportData = [PSCustomObject]@{
Name = $UserDataRow.Name
IP = $UserDataRow.Group.IP
}
$UserIPReportData
}
}

Clear-Host
Get-UserIPReport

Name IP
—- —
SYSTEM {192.168.137.1, 192.168.137.2}
admin 172.16.2.1

$UserIPData = Get-UserIPReport
$UserIPData[0]

Name IP
—- —
SYSTEM {192.168.137.1, 192.168.137.2}

$UserIPData[0].Name
SYSTEM

$UserIPData[0].IP[0]
192.168.137.1

Or More succinctly, this way
Function Get-UserIPReport
{
$UserData = ($(foreach ($IPDataRow in (Get-Content '.\UserIPObjects.txt'))
{$IPDataRow}) |
Get-Unique) -replace ' ',',' |
ConvertFrom-Csv |
Group User

ForEach($UserDataRow in $UserData)
{
$UserIPReportData = [PSCustomObject]@{
Name = $UserDataRow.Name
IP = $UserDataRow.Group.IP
}
$UserIPReportData
}
}
Clear-Host
($UserDataArray = Get-UserIPReport)

Name IP
—- —
SYSTEM {192.168.137.1, 192.168.137.2}
admin 172.16.2.1

$UserDataArray[0]

Name IP
—- —
SYSTEM {192.168.137.1, 192.168.137.2}

$UserDataArray[0].Name
SYSTEM

$UserDataArray[0].IP
192.168.137.1
192.168.137.2