Reputation: 251
I have an array of Objects that have 6 properties. That look like this:
$csvData
CURRENT DATE AND TIME : 07/10/2015 08:17:17 CST
USER NAME : userName
COMPUTER NAME : computerName
IP ADDRESS : 192.168.1.1
LOGON SERVER : logonServer
LOGON/OFF : logon
I want to create an array of objects where username and computer name are not duplicated. How can I get only the unique username/computername combo in powershell? Ultimately I would like to remove all duplicates and add a property 'Count' that keeps track of how many duplicates there are.
I have tried:
$csvDataUnique = $csvData | Select-Object 'User Name','Computer Name' -Unique
$csvDataUnique = $csvData | sort -Property 'User Name' | Get-Unique
Upvotes: 25
Views: 40541
Reputation: 125
The other answers didn't retain the rest of the properties in the final output. This should work for you:
$csvDataUnique = $csvData | Group-Object -Property 'User Name', 'Computer Name' | ForEach-Object { $_.Group[0] }
Upvotes: 6
Reputation: 2952
An alternative option is to use Get-Unique
.
It was quite helpful in my situation when I wanted to select objects based on a unique property without some extensive foreach-loop.
$csvData | Sort-Object 'User Name', 'Computer Name' | Get-Unique -AsString
The object needs to be sorted because Get-Unique
compares the strings adjacent to each other. Additionally, the comparison is case-sensitive.
Upvotes: 3
Reputation: 406
Very similar to Mathias' answer, but will have all of the columns in the output:
$csvDataUnique = $csvData |
Group-Object 'User Name','Computer Name' |
%{ $_.Group | Select 'User Name','Computer Name' -First 1} |
Sort 'User Name','Computer Name'
Upvotes: 26
Reputation: 174575
You can use Group-Object
to group by multiple properties:
$Uniqs = $csvData | Group -Property "USER NAME","COMPUTER NAME" -NoElement | Select -Expand Name
Upvotes: 1
Reputation: 2917
You can create a custom property with your Select-Object
. So you were pretty close already. Try this:
Select-Object @{Label = "Index"; Expression = {"$($_.'User Name') $($_.'Computer Name')"} } -Unique
It basically combines the two fields into a single string and sorts unique on that. I called the field "Index" but it could be called anything.
Upvotes: 6
Reputation: 68293
I usually resort to using a hash table, and joined property values for the keys for that kind of task:
$CSVDataUnique = @{}
$csvData | foreach {
$CSVDataUnique["$_.'User Name'\$_.'Computer Name'"]++
}
Upvotes: 1