User Tools

Site Tools


microsoft_windows:terminalserver:logs

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
microsoft_windows:terminalserver:logs [2020/03/09 16:16] rodolicomicrosoft_windows:terminalserver:logs [2020/03/10 01:45] (current) rodolico
Line 3: Line 3:
 Microsoft hides the Remote Desktop logins pretty deep in their logging structure and there is not much information on how to programmatically get to it. I have a client who needed to get to this, so I figured I'd record what I came up with and some links. Microsoft hides the Remote Desktop logins pretty deep in their logging structure and there is not much information on how to programmatically get to it. I have a client who needed to get to this, so I figured I'd record what I came up with and some links.
  
-There is a lot of documentation on how to do this if you are running a Windows Domain, but in the main case here, that is not the case.+There is a lot of documentation on how to do this if you are running a Windows Domain, but in the main case here, that is not the case. This procedure works on machines which are not on a domain, looking a the local server and parsing the local log files.
  
 This has been tested on Windows 7, Server 2008r2 and Server 2019, the latter two running as Terminal Services servers. This has been tested on Windows 7, Server 2008r2 and Server 2019, the latter two running as Terminal Services servers.
Line 13: Line 13:
 # https://serverfault.com/questions/479048/remote-desktop-services-login-history # https://serverfault.com/questions/479048/remote-desktop-services-login-history
  
 +# get date range from user
 +# NOTE: might be good to get EventID we are looking for also
 do { do {
     $startDate = Read-Host "Enter the reports start date as dd/mm/yyyy";     $startDate = Read-Host "Enter the reports start date as dd/mm/yyyy";
Line 20: Line 22:
 } while ( $startDate -isnot [datetime] -And $endDate -isnot [datetime] ) } while ( $startDate -isnot [datetime] -And $endDate -isnot [datetime] )
  
 +# this was used when it was a static entry, but unused now
 #$startDate = (Get-Date -Year $year -Month $month -Day 01) #$startDate = (Get-Date -Year $year -Month $month -Day 01)
 #$endDate = (Get-Date -Year 2020 -Month 03 -Day 01) #$endDate = (Get-Date -Year 2020 -Month 03 -Day 01)
  
 +# name of the log to read. This contains activity on the Terminal Services
 $LogName = 'Microsoft-Windows-TerminalServices-LocalSessionManager/Operational' $LogName = 'Microsoft-Windows-TerminalServices-LocalSessionManager/Operational'
 +# we'll store results in this array
 $Results = @() $Results = @()
 +# Get all events. See 
 +# https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.diagnostics/get-winevent?view=powershell-7
 +# for additional parameters. We might be able to speed processing with
 +# Get-WinEvent -LogName $LogName | Where-Object { $_.TimeCreated -ge $startDate -And $_.TimeCreated -le $endDate
 $Events = Get-WinEvent -LogName $LogName $Events = Get-WinEvent -LogName $LogName
 +# loop through all the events we found
 foreach ($Event in $Events) { foreach ($Event in $Events) {
 +    # convert to xml?
     $EventXml = [xml]$Event.ToXML()     $EventXml = [xml]$Event.ToXML()
-    if ( $Event.Id -eq 25 -And $Event.TimeCreated -ge $startDate -And $Event.TimeCreated -lt $endDate ) {+    # filter for the event.id and between the dates (inclusive) 
 +    if ( $Event.Id -eq 25 -And $Event.TimeCreated -ge $startDate -And $Event.TimeCreated -le $endDate ) { 
 +        # found one, so plug the stuff into a hash
         $ResultHash = @{         $ResultHash = @{
             Time        = $Event.TimeCreated.ToString()             Time        = $Event.TimeCreated.ToString()
Line 37: Line 50:
             'Details'   = $Event.Message             'Details'   = $Event.Message
         }         }
 +        # then, take the result and append it to our results array
         $Results += (New-Object PSObject -Property $ResultHash)         $Results += (New-Object PSObject -Property $ResultHash)
     }     }
- 
 } }
 +# figure out where to put the file
 $currentDir = $(get-location).Path; $currentDir = $(get-location).Path;
 +# and create a file name from the path and the start/end date
 $currentDir = "$currentDir" + '\RemoteDesktopUsers_' + $startDate.ToString("yyyy-MM-dd") + '_' + $endDate.ToString("yyyy-MM-dd") + '.csv'; $currentDir = "$currentDir" + '\RemoteDesktopUsers_' + $startDate.ToString("yyyy-MM-dd") + '_' + $endDate.ToString("yyyy-MM-dd") + '.csv';
 +# dump it as CSV so they can read it via a spreadsheet.
 $Results | Export-Csv -Path $currentDir; $Results | Export-Csv -Path $currentDir;
 </code> </code>
 +
 +The above script first asks for a start and end date for parsing, then opens //Microsoft-Windows-TerminalServices-LocalSessionManager/Operational// to get the logs. It then goes through each entry, looking for event type 25 (user logins) which fall in the date range. Once it has found all of them, it dumps the retrieved output to the same directory the script was run from as RemoteDesktopUsers_startdate_enddate.csv, a comma separated file which can be read by Excel or LibreOffice Calc.
  
 ===== Running the script ===== ===== Running the script =====
microsoft_windows/terminalserver/logs.txt · Last modified: 2020/03/10 01:45 by rodolico