Search code examples
powershellselect-object

Group and select objects from CSV in PowerShell


I have a list of users their device(s) and their managers. The manager and user can be duplicates but the deviceID is unique. How do I get a list so I can send every manager an email to let them know how many and which unit their employees are using? I am only interested in people with 2 or more devices.

Wanted output would be something like this (if anyone wants to give me a better output suggestion I am all ears).

Manager  deviceID
M1        U1=D1 D2, U3=D4 D5

What my code looks like now:

$csv = @"
manager,user,deviceID
M1,U1,D1
M1,U1,D2
M2,U2,D3
M1,U3,D4
M1,U3,D5
"@ -split "`r`n" | ConvertFrom-Csv

$csv | Group-Object -Property Manager |
     Select-Object @{N='Manager';E={($_.Group[0]).Manager}}, 
@{N="User";E={($_.group).user}}, 
@{N="deviceID";E={ foreach($row in $_.Group){ $row.user + ' = ' + $row.deviceID}}} 

Solution

  • Since you say you are only interested in listing the users that use more than one device, perhaps this could help you:

    $csv = @"
    manager,user,deviceID
    M1,U1,D1
    M1,U1,D2
    M2,U2,D3
    M1,U3,D4
    M1,U3,D5
    "@ -split "`r`n" | ConvertFrom-Csv
    
    # first group on Manager
    $result = $csv | Group-Object -Property Manager | ForEach-Object {
        $manager = $_.Name
        # next, group the groups on User and select only where a user is mentioned twice or more times
        $_.Group | Group-Object User | Where-Object { $_.Count -gt 1 } | ForEach-Object {
            [PsCustomObject]@{
                Manager = $manager
                User = $_.Name
                Devices = $_.Group.DeviceID -join ' '
            }
        }
    }
    
    # output on screen
    $result
    
    # output to CSV
    $result | Export-Csv -Path 'managerReport.csv' -NoTypeInformation
    

    Output:

    Manager User Devices
    ------- ---- -------
    M1      U1   D1 D2  
    M1      U3   D4 D5
    
    # to separate the results so each manager gets his/her personal report:
    $result | Group-Object Manager | ForEach-Object {
        # send an email to the manager. For demo just output to console
        Write-Host "Send mail to manager $($_.Name):" -ForegroundColor Yellow
        $_.Group | Format-Table -AutoSize | Out-String
    }