Search code examples
powershellpowershell-3.0rdp

Import CSV and group by name and then first instance of datetime


I am trying to get RDP session event( event ID: 22 and 25) for a number of computers and export as a CSV file. I need to get the first instance of a RDP session the user has initiated on each day( There may be many RDP session reconnection/day) so I can create a report what time each user is initiating the first RDP session.

$week = (Get-Date) - (New-TimeSpan -Day 10)
$Events = Get-WinEvent  -ComputerName $ComputerName -LogName $LogName | Where-Object { ($_.TimeCreated -ge $week) -and (($_.Id -eq '22') -or ($_.Id -eq '25')) }  
  
foreach ($Event in $Events) {
    $EventXml = [xml]$Event.ToXML()
    $EventTime = $Event.TimeCreated.ToString()
    $Username = $EventXml.Event.UserData.EventXML.User
}

The CSV file has the time column which contains the connection time in (mm/dd/yyyy HH:mm) format. I am struggling to get the group and sort command to get the first instance of a connection in each day.

Any help will be much appreciated.


Solution

  • I added lots of comments to help you with the thought process

    $logFilter=@{
        LogName='Microsoft-Windows-TerminalServices-LocalSessionManager/Operational'
        ID=22,25
        StartTime=[datetime]::Now.Adddays(-30)
    }
    
    # Get all events 22 & 25 for the past 30 days
    $events=Get-WinEvent -FilterHashtable $logFilter
    
    # Since we want the first Event per Date, we need to 
    # group all events by each Day
    $groupByDay=$Events|Group-Object {$_.TimeCreated.ToShortDateString()}
    
    # Looks like this
    PS /> $groupByDay
    
    Count Name                      Group                                                                                                       
    ----- ----                      -----                                                                                                       
       68 5/4/2021                  {System.Diagnostics.Even...
       76 5/3/2021                  {System.Diagnostics.Even...
       12 5/2/2021                  {System.Diagnostics.Even...
       22 5/1/2021                  {System.Diagnostics.Even...
       62 4/30/2021                 {System.Diagnostics.Even...
       46 4/29/2021                 {System.Diagnostics.Even...
    
    # Now we want to group each day by User and get the first log for each one of them
    # To see an example of how it looks you can use this =>
    $groupByDay[0].Group|Group-Object {$_.Properties.Value[0]}
    
    # Note
    $events[0].Properties.Value[0]
    # Is the same as
    ([xml]$events[0].ToXml()).Event.UserData.EventXML.User
    
    # Create a new export grid
    $grid=[collections.generic.list[pscustomobject]]::new()
    
    # For each day in all days logs
    foreach($group in $groupByDay)
    {
        $groupByUsers=$group.Group|Group-Object {$_.Properties.Value[0]}
    
        foreach($user in $groupByUsers)
        {
            # Logs are always sorted by newest to oldest
            # we can assume that the first log we get from pipeline
            # is the one we want for each user
            $temp=$user.group|Select -First 1
    
            # Add this object to our export grid
            $grid.Add(
                [pscustomobject]@{
                    Time=$temp.TimeCreated.ToString('MM/dd/yyyy HH:mm')
                    EventID=$temp.Id
                    User=$user.Name
            })
        }
    }
    

    Export should look something like this:

    Time EventID User
    05/04/2021 16:00 25 user.example1
    05/04/2021 15:55 25 user.example2
    05/04/2021 14:40 22 user.example3
    05/03/2021 16:00 25 user.example1
    05/03/2021 15:55 25 user.example2
    05/03/2021 14:40 22 user.example3