├── README.md └── Teamviewer.ps1 /README.md: -------------------------------------------------------------------------------- 1 | # TeamViewer_Forensics 2 | A series of functions to parse Teamviewer logs to answer specific questions 3 | 4 | # Logs of Interest 5 | * C:\ProgramFiles(x86)\Teamviewer\Connections_incoming.txt 6 | * Contains logs of successful connections to the system 7 | * Contains the following Properties: Teamviewer ID of the connecting device, display name, start time, end time, the username of logged on user, connection type, and the connection ID 8 | * Depicted time in the log is in UTC 9 | 10 | * C:\ProgramFiles(x86)\Teamviewer\TeamViewer15_Logfile.log 11 | * Contains verbose information for troubleshooting 12 | * Contains verbose logging of incoming and outgoing connections that can be used to: 13 | * identify successful and unsuccessful incoming or outgoing connections 14 | * identify settings and characteristics about the connecting system 15 | * identify the public IP (or assigned IP) of the connecting system 16 | * PID associated with the Teamviewer program 17 | * Depicted time in the log is local time to the system 18 | 19 | * C:\ProgramFiles(x86)\Teamviewer\TeamViewer15_Logfile_OLD.log 20 | * Rollover log of C:\ProgramFiles(x86)\Teamviewer\TeamViewer15_Logfile.log 21 | 22 | * C:\Users\\AppData\Roaming\TeamViewer\MRU\RemoteSupport\*tvc 23 | * Files are artifacts of successful connections 24 | * The data from the file populates the dropdown list under "Partner ID" in the program's GUI 25 | 26 | * C:\Users\\AppData\Roaming\TeamViewer\connections.txt 27 | * Contains logs of successful outgoing connections 28 | * Contains the following Properties: Teamviewer ID of the connecting device, start time, end time, the username of logged on user, connection type, and the connection ID 29 | * Depicted time in the log is in UTC 30 | 31 | # Questions that can be Answered 32 | * What outgoing connections haas this machine made? 33 | * Of those connections, which connections were the successful and unsuccessful? 34 | * What incoming connections were made to this machine? 35 | * What PID was tied to that connection and were there child process spawned? 36 | * What IPs are communicating with this machine? 37 | * What Teamviewer IDs communicated with this machine? 38 | * What is the keyboard layout associated with the incoming connection? 39 | * Were there any files transmitted during the incoming connection? 40 | * What is the duration of the incoming and outgoing connection? 41 | * How long does the Teamviewer process run, on average? 42 | 43 | # Disclaimer 44 | While the questions are valid for all versions of Teamviewer, the code was only tested with Teamviewer 15. 45 | 46 | -------------------------------------------------------------------------------- /Teamviewer.ps1: -------------------------------------------------------------------------------- 1 | function Get-TVIncomingLog_byDate{ 2 | <# 3 | .SYNOPSIS 4 | Parses the connections_incoming.txt file and returns data before, after, or between a specific date 5 | 6 | .PARAMETER File 7 | Location to the connections_incoming.txt file 8 | 9 | .PARAMETER BeforeDate 10 | Returns data before the specified date 11 | 12 | .PARAMETER AfterDate 13 | Returns data after the specified date 14 | 15 | .EXAMPLE 16 | Get-TVIncomingLog_byDate -file "C:\Program Files (x86)\TeamViewer\connections_incoming.txt" -before "12/25/2020" 17 | 18 | Returns data before December 25, 2020 19 | 20 | .EXAMPLE 21 | Get-TVIncomingLog_byDate -file "C:\Program Files (x86)\TeamViewer\connections_incoming.txt" -after "12/25/2020" 22 | 23 | Returns data after December 25, 2020 24 | 25 | .EXAMPLE 26 | Get-TVIncomingLog_byDate -file "C:\Program Files (x86)\TeamViewer\connections_incoming.txt" -before "3/1/2021" -after "12/25/2020" 27 | 28 | Returns data after March 1, 2021 before December 25, 2020 29 | #> 30 | 31 | [CmdletBinding()] 32 | param( 33 | $File, 34 | $BeforeDate, 35 | $AfterDate 36 | ) 37 | $logs = get-content $file 38 | 39 | $obj = @() 40 | $logs = $logs -replace (' ','_') 41 | $obj = foreach($log in $logs){ 42 | $dur = '' 43 | $log = $log -split "\s+" 44 | $log = $log -replace ('_',' ') 45 | try{ 46 | $log[2]= [datetime]::ParseExact($log[2],'dd-MM-yyyy HH:mm:ss', $null) 47 | } catch{ } 48 | try{ 49 | $log[3]= [datetime]::ParseExact($log[3],'dd-MM-yyyy HH:mm:ss', $null) 50 | } catch { } 51 | $dur = New-TimeSpan -start $log[2] -end $log[3] -ErrorAction SilentlyContinue 52 | [PSCustomObject]@{ 53 | IncomingID = $log[0] 54 | DisplayName = $log[1] 55 | StartDate = $log[2] 56 | EndDate = $log[3] 57 | Duration = [string]$dur.ToString("dd'd.'hh'h:'mm'm:'ss's'") 58 | LoggedOnUser = $log[4] 59 | ConnectionType = $log[5] 60 | ConnectionID = $log[6] 61 | } 62 | } 63 | 64 | if($afterDate -and $beforeDate){ 65 | $obj |where-object{$_.startdate -gt $afterDate -and $_.startdate -lt $beforeDate} 66 | } 67 | elseif($afterDate){ 68 | $obj |where-object{$_.startdate -gt $afterDate} 69 | } 70 | elseif($beforeDate){ 71 | $obj |where-object{$_.startdate -lt $beforeDate} 72 | } 73 | } 74 | 75 | function Get-TVIncomingLog_Top10Duration{ 76 | <# 77 | .SYNOPSIS 78 | Parses the connections_incoming.txt file and returns the duration for the top 10 longest or shortest incoming connections 79 | 80 | .PARAMETER File 81 | Location to the connections_incoming.txt file 82 | 83 | .PARAMETER shortest 84 | Used select the shortest connections 85 | 86 | .PARAMETER longest 87 | Used select the longest connections 88 | 89 | .EXAMPLE 90 | Get-TVIncomingLog_Top10Duration -file "C:\Program Files (x86)\TeamViewer\connections_incoming.txt" 91 | 92 | Returns the duration for all incoming connections 93 | 94 | .EXAMPLE 95 | Get-TVIncomingLog_Top10Duration -file "C:\Program Files (x86)\TeamViewer\connections_incoming.txt" -shortest 96 | 97 | Returns the top 10 shortest durations for all incoming connections 98 | 99 | .EXAMPLE 100 | Get-TVIncomingLog_Top10Duration -file "C:\Program Files (x86)\TeamViewer\connections_incoming.txt" -longest 101 | 102 | Returns the top 10 longest durations for all incoming connections 103 | #> 104 | [CmdletBinding()] 105 | param( 106 | $File, 107 | [switch]$shortest, 108 | [switch]$longest 109 | ) 110 | $logs = get-content $file 111 | 112 | $obj = @() 113 | $logs = $logs -replace (' ','_') 114 | $obj = foreach($log in $logs){ 115 | $dur = '' 116 | $log = $log -split "\s+" 117 | $log = $log -replace ('_',' ') 118 | try{ 119 | $log[2]= [datetime]::ParseExact($log[2],'dd-MM-yyyy HH:mm:ss', $null) 120 | } catch{ } 121 | try{ 122 | $log[3]= [datetime]::ParseExact($log[3],'dd-MM-yyyy HH:mm:ss', $null) 123 | } catch { } 124 | $dur = New-TimeSpan -start $log[2] -end $log[3] -ErrorAction SilentlyContinue 125 | [PSCustomObject]@{ 126 | IncomingID = $log[0] 127 | DisplayName = $log[1] 128 | StartDate = $log[2] 129 | EndDate = $log[3] 130 | Duration = [string]$dur.ToString("dd'd.'hh'h:'mm'm:'ss's'") 131 | LoggedOnUser = $log[4] 132 | ConnectionType = $log[5] 133 | ConnectionID = $log[6] 134 | } 135 | } 136 | if($shortest){ 137 | $obj | Sort-Object Duration -Top 10 | Format-Table 138 | } 139 | if($longest){ 140 | $obj | Sort-Object Duration -Bottom 10 | Format-Table 141 | } 142 | } 143 | 144 | function Get-TVIncomingLog_Unique{ 145 | <# 146 | .SYNOPSIS 147 | Parses the connections_incoming.txt and returns the unique incoming IDs, display names, or logged on users 148 | 149 | .PARAMETER File 150 | Location to the connections_incoming.txt file 151 | 152 | .PARAMETER IncomingID 153 | Used to select the returning of unique incoming IDs 154 | 155 | .PARAMETER DisplayName 156 | Used to select the returning of unique display names 157 | 158 | .PARAMETER LoggedOnUser 159 | Used to select the returning of unique logged on users 160 | 161 | .EXAMPLE 162 | Get-TVIncomigLog_Unique -file "C:\Program Files (x86)\TeamViewer\connections_incoming.txt" -incomingid 163 | 164 | Returns the entries containing unique incoming IDs 165 | 166 | .EXAMPLE 167 | Get-TVIncomigLog_Unique -file "C:\Program Files (x86)\TeamViewer\connections_incoming.txt" -displayname 168 | 169 | Returns the entries containing unique display names 170 | 171 | .EXAMPLE 172 | Get-TVIncomigLog_Unique -file "C:\Program Files (x86)\TeamViewer\connections_incoming.txt" -loggedonuser 173 | 174 | Returns the entries containing unique logged on user 175 | 176 | #> 177 | [CmdletBinding()] 178 | param( 179 | $File, 180 | [switch]$IncomingID, 181 | [switch]$DisplayName, 182 | [switch]$LoggedOnUser 183 | 184 | ) 185 | $logs = get-content $file 186 | 187 | $obj = @() 188 | $logs = $logs -replace (' ','_') 189 | $obj = foreach($log in $logs){ 190 | $dur = '' 191 | $log = $log -split "\s+" 192 | $log = $log -replace ('_',' ') 193 | try{ 194 | $log[2]= [datetime]::ParseExact($log[2],'dd-MM-yyyy HH:mm:ss', $null) 195 | } catch{ } 196 | try{ 197 | $log[3]= [datetime]::ParseExact($log[3],'dd-MM-yyyy HH:mm:ss', $null) 198 | } catch { } 199 | $dur = New-TimeSpan -start $log[2] -end $log[3] -ErrorAction SilentlyContinue 200 | [PSCustomObject]@{ 201 | IncomingID = $log[0] 202 | DisplayName = $log[1] 203 | StartDate = $log[2] 204 | EndDate = $log[3] 205 | Duration = [string]$dur.ToString("dd'd.'hh'h:'mm'm:'ss's'") 206 | LoggedOnUser = $log[4] 207 | ConnectionType = $log[5] 208 | ConnectionID = $log[6] 209 | } 210 | } 211 | if($IncomingID){ 212 | $obj | Sort-Object -Property incomingid -Unique | select-object incomingid 213 | } 214 | elseif($DisplayName){ 215 | $obj | Sort-Object -Property displayname -Unique | select-object displayname 216 | } 217 | elseif($LoggedOnUser){ 218 | $obj | Sort-Object -Property LoggedOnUser -Unique | select-object LoggedOnUser 219 | } 220 | } 221 | 222 | function Get-TVLogFile_RunTimes{ 223 | <# 224 | .SYNOPSIS 225 | Parses the Teamviewer15_logfile.log and Teamviewer15_logfile_OLD.log for the run time of the Teamviewer program 226 | 227 | .PARAMETER directory 228 | Used to specify the directory containing the log files 229 | 230 | .EXAMPLE 231 | Get-TVLogFile_RunTimes -directory "C:\Program Files (x86)\TeamViewer" 232 | 233 | Will search the specified directory and parse the log files, returning the run time of the Teamviewer program 234 | #> 235 | [CmdletBinding()] 236 | param( 237 | $directory 238 | ) 239 | $logs = Get-ChildItem ($directory + "\teamviewer15_Logfile*.log") 240 | 241 | $obj = @() 242 | $obj = foreach($line in $logs.fullname){ 243 | $logfile = Get-Content $line | select-string -Pattern '(2]::processconnected:) | (Closing TeamViewer)' 244 | 245 | foreach($item in $logfile){ 246 | $data = $shutdownData = ' ' 247 | if ($item -like "*2]::processconnected: *"){ 248 | $data = $item.line -split ' ' 249 | $data = $data[0]+' '+$data[1] 250 | $data = ([datetime]$data).ToString("MM/dd/yyyy HH:mm:ss") 251 | $index = ($logfile.IndexOf($item) + 1) 252 | if($logfile[$index] -match "Closing Teamviewer"){ 253 | $shutdownData = $item.line -split ' ' 254 | $shutdownData = $shutdownData[0]+' '+$shutdownData[1] 255 | $shutdownData = ([datetime]$shutdownData).ToString("MM/dd/yyyy HH:mm:ss") 256 | } 257 | [pscustomobject]@{ 258 | ProgramStart = $data 259 | ProgramEnd = $shutdownData 260 | } 261 | } 262 | } 263 | } 264 | } 265 | 266 | function Get-TVLogFile_AccountLogons{ 267 | <# 268 | .SYNOPSIS 269 | Parses the Teamviewer15_logfile.log and Teamviewer15_logfile_OLD.log for the account names 270 | 271 | .PARAMETER directory 272 | Used to specify the directory containing the log files 273 | 274 | .EXAMPLE 275 | Get-TVLogFile_AccountLogons -directory "C:\Program Files (x86)\TeamViewer" 276 | 277 | Returns the account names 278 | 279 | #> 280 | [CmdletBinding()] 281 | param( 282 | $directory 283 | ) 284 | 285 | $logs = Get-ChildItem ($directory + "\teamviewer15_Logfile*.log") 286 | 287 | $obj = @() 288 | $obj = foreach($line in $logs.fullname){ 289 | $logfile = Get-Content $file | select-string -Pattern "HandleLoginFinished: Authentication successful", "Account::Logout: Account session terminated successfully" 290 | foreach($item in $logfile){ 291 | $data = $logoutData = ' ' 292 | if ($item.Matches.value -like "*authentication*"){ 293 | $data = $item.line -split ' ' 294 | $data = $data[0]+' '+$data[1] 295 | $data = ([datetime]$data).ToString("MM/dd/yyyy HH:mm:ss") 296 | 297 | } 298 | else{ 299 | $Data = "--" 300 | } 301 | if($item.Matches.value -like "*terminated*"){ 302 | $logoutData = $item.line -split ' ' 303 | $logoutData = $logoutData[0]+ ' '+$logoutData[1] 304 | $logoutData = ([datetime]$logoutData).ToString("MM/dd/yyyy hh:mm:ss") 305 | } 306 | else{ 307 | $logoutData = "--" 308 | } 309 | [pscustomobject]@{ 310 | AccountLogon = $data 311 | AccountLogout = $logoutData 312 | } 313 | } 314 | } 315 | } 316 | 317 | function Get-TVLogFile_IPs{ 318 | <# 319 | .SYNOPSIS 320 | Parses the Teamviewer15_logfile.log and Teamviewer15_logfile_OLD.log for a list of IPs used for incoming connections 321 | 322 | .PARAMETER directory 323 | Used to specify the directory containing the log files 324 | 325 | .EXAMPLE 326 | Get-TVLogFile_IPs -directory "C:\Program Files (x86)\TeamViewer" 327 | 328 | Returns the IPs used during the incoming connections 329 | #> 330 | [CmdletBinding()] 331 | param( 332 | $directory 333 | ) 334 | 335 | $logs = Get-ChildItem ($directory + "\teamviewer15_Logfile*.log") 336 | 337 | $obj = @() 338 | $obj = foreach($logfile in $logs.fullname){ 339 | $temp = get-content $logfile | select-string "punch\sreceived.*?[0-9]{3}\.[0-9]{3}\.[0-9]{1,}\.[0-9]{1,}\:.*?\:", "punch\sreceived.*?a=.*?\:[0-9]{5}\:" 340 | foreach($line in $temp){ 341 | try{ 342 | $tempSplit = $line -split ('=') 343 | $date = $data = ($line -split(''))[0..19] -join('') 344 | $date = ([datetime]$date).ToString("MM/dd/yyyy HH:mm:ss") 345 | if($tempSplit[1].length -gt 22){ 346 | $ip = $tempSplit[1].trim(': (*)') 347 | $comm[0] = $ip[0..(($ip).length - 7)] -join('') 348 | $comm[1] = $ip[-5..-1] -join('') 349 | } 350 | else{ 351 | $comm = ($tempSplit[1].trim(': (*)')) -split (':') 352 | } 353 | } catch{ } 354 | 355 | [pscustomobject]@{ 356 | Date = $date 357 | IP = $comm[0] 358 | SrcPort = $comm[1] 359 | } 360 | } 361 | } 362 | } 363 | 364 | Function Get-TVLogFile_PIDs{ 365 | <# 366 | .SYNOPSIS 367 | Parses the Teamviewer15_logfile.log and Teamviewer15_logfile_OLD.log and returns the PID for the connection 368 | 369 | .PARAMETER directory 370 | Used to specify the directory containing the log files 371 | 372 | .EXAMPLE 373 | Get-TVLogFile_PIDs -directory "C:\Program Files (x86)\TeamViewer" 374 | 375 | Returns the PIDs associated with the incoming connection 376 | #> 377 | [CmdletBinding()] 378 | param( 379 | $directory 380 | ) 381 | 382 | $logs = Get-ChildItem ($directory + "\teamviewer15_Logfile*.log") 383 | 384 | $obj = @() 385 | $obj = foreach($log in $logs.fullname){ 386 | $temp = get-content $log | select-string "Start Desktop process" 387 | foreach($line in $temp){ 388 | $split = $line -Split(' ') 389 | $data = $split[0]+' '+$split[1] 390 | $data = ([datetime]$data).ToString("MM/dd/yyyy HH:mm") 391 | [pscustomobject]@{ 392 | Date = $data 393 | PID = $split[-1] 394 | } 395 | } 396 | } 397 | } 398 | 399 | Function Get-TVLogFile_Outgoing{ 400 | <# 401 | .SYNOPSIS 402 | Parses the Teamviewer15_logfile.log and Teamviewer15_logfile_OLD.log and returns outgoing connections (successes and failures) 403 | 404 | .PARAMETER directory 405 | Used to specify the directory containing the log files 406 | 407 | .EXAMPLE 408 | Get-TVLogFile_Outgoing -directory "C:\Program Files (x86)\TeamViewer" 409 | 410 | Returns the outgoing connections (successes and failures) 411 | #> 412 | [CmdletBinding()] 413 | param( 414 | $directory 415 | ) 416 | $logs = Get-ChildItem ($directory + "\teamviewer15_Logfile*.log") 417 | 418 | $obj = @() 419 | $obj = foreach($log in $logs.fullname){ 420 | $temp = get-content $log | select-string "trying connection to", "LoginOutgoing: ConnectFinished - error: KeepAliveLost" 421 | foreach($line in $temp){ 422 | $tvID = $success = ' ' 423 | $split = $line -Split(' ') 424 | if($line -like "*mode = 1"){ 425 | $tvID = ($split[-4]).trim(',') 426 | $index = ($temp.IndexOf($line) + 1) 427 | if($temp[$index] -match "KeepAliveLost"){ 428 | $success = "No" 429 | } 430 | else{ 431 | $success = "Yes" 432 | } 433 | $data = $split[0]+' '+$split[1] 434 | $data = ([datetime]$data).ToString("MM/dd/yyyy HH:mm:ss") 435 | [pscustomobject]@{ 436 | Date = $data 437 | ID = $tvID 438 | Successful = $success 439 | # Duration = 440 | } 441 | 442 | } 443 | else{ 444 | 445 | } 446 | 447 | } 448 | } 449 | } 450 | 451 | Function Get-TVLogFile_KeyboardLayout{ 452 | <# 453 | .SYNOPSIS 454 | Parses the Teamviewer15_logfile.log and Teamviewer15_logfile_OLD.log and returns the keyboard layout associated with the incoming connection 455 | 456 | .PARAMETER directory 457 | Used to specify the directory containing the log files 458 | 459 | .EXAMPLE 460 | Get-TVLogFile_KeyboardLayout -directory "C:\Program Files (x86)\TeamViewer" 461 | 462 | Reurtns the keyboard layout associated with the incoming connection 463 | #> 464 | [CmdletBinding()] 465 | param( 466 | $directory 467 | ) 468 | 469 | $logs = Get-ChildItem ($directory + "\teamviewer15_Logfile*.log") 470 | 471 | $obj = @() 472 | $obj = foreach($log in $logs.fullname){ 473 | $temp = get-content $log | select-string "changing keyboard layout to" 474 | foreach($line in $temp){ 475 | $split = $line -Split(' ') 476 | $data = $split[0]+' '+$split[1] 477 | $data = ([datetime]$data).ToString("MM/dd/yyyy HH:mm") 478 | [pscustomobject]@{ 479 | Date = $data 480 | Keyboard = $split[-1] 481 | } 482 | } 483 | } 484 | } 485 | 486 | function Get-TVConnectionsLog_byDate{ 487 | <# 488 | .SYNOPSIS 489 | Parses the connections.txt and returns data before, after, or between a specific date 490 | 491 | .DESCRIPTION 492 | Location to the connections.txt file 493 | 494 | .PARAMETER BeforeDate 495 | Returns data before the specified date 496 | 497 | .PARAMETER AfterDate 498 | Returns data after the specified date 499 | 500 | .EXAMPLE 501 | Get-TVConnectionsLog_byDate -file "C:\Users\\AppData\Roaming\TeamViewer\connections.txt" -before "12/25/2020" 502 | 503 | Returns data before December 25, 2020 504 | 505 | .EXAMPLE 506 | Get-TVConnectionsLog_byDate -file "C:\Users\\AppData\Roaming\TeamViewer\connections.txt" -after "12/25/2020" 507 | 508 | Returns data after December 25, 2020 509 | 510 | .EXAMPLE 511 | Get-TVConnectionsLog_byDate -file "C:\Users\\AppData\Roaming\TeamViewer\connections.txt" -before "3/1/2021" -after "12/25/2020" 512 | 513 | Returns data after March 1, 2021 before December 25, 2020 514 | #> 515 | [CmdletBinding()] 516 | param( 517 | $File, 518 | $BeforeDate, 519 | $AfterDate 520 | ) 521 | $logs = get-content $file 522 | 523 | $obj = @() 524 | $obj = foreach($log in $logs){ 525 | $dur = '' 526 | $log = $log -split '\s+' 527 | $dataStart = $log[1]+' '+$log[2] 528 | $dataEnd = $log[3]+' '+$log[4] 529 | try{ 530 | $dataStart = [datetime]::ParseExact($dataStart,'dd-MM-yyyy HH:mm:ss', $null) 531 | } catch { } 532 | try{ 533 | $dataEnd = [datetime]::ParseExact($dataEnd,'dd-MM-yyyy HH:mm:ss', $null) 534 | } catch { } 535 | try{ 536 | $dur = New-TimeSpan -start $dataStart -end $dataEnd -ErrorAction SilentlyContinue 537 | [PSCustomObject]@{ 538 | IncomingID = $log[0] 539 | StartDate = $dataStart 540 | EndDate = $dataEnd 541 | Duration = [string]$dur.ToString("dd'd.'hh'h:'mm'm:'ss's'") 542 | LoggedOnUser = $log[5] 543 | ConnectionType = $log[6] 544 | ConnectionID = $log[7] 545 | } 546 | } catch { } 547 | } 548 | 549 | if($afterDate -and $beforeDate){ 550 | $obj |where-object{$_.startdate -gt $afterDate -and $_.startdate -lt $beforeDate} 551 | } 552 | elseif($afterDate){ 553 | $obj |where-object{$_.startdate -gt $afterDate} 554 | } 555 | elseif($beforeDate){ 556 | $obj |where-object{$_.startdate -lt $beforeDate} 557 | } 558 | } 559 | 560 | function Get-TVConnectionsLog_Top10Duration{ 561 | <# 562 | .SYNOPSIS 563 | Parses the connections.txt file and returns the duration for the top 10 longest or shortest outgoing connections 564 | 565 | .PARAMETER File 566 | Location to the connections.txt file 567 | 568 | .PARAMETER shortest 569 | Used select the shortest connections 570 | 571 | .PARAMETER longest 572 | Used select the longest connections 573 | 574 | .EXAMPLE 575 | Get-TVConnectionsLog_Top10Duration -file "C:\Users\\AppData\Roaming\TeamViewer\connections.txt" 576 | 577 | Returns the duration for all outgoing connections 578 | 579 | .EXAMPLE 580 | Get-TVConnectionsLog_Top10Duration -file "C:\Users\\AppData\Roaming\TeamViewer\connections.txt" -shortest 581 | 582 | Returns the top 10 shortest durations for all outgoing connections 583 | 584 | .EXAMPLE 585 | Get-TVConnectionsLog_Top10Duration -file "C:\Users\\AppData\Roaming\TeamViewer\connections.txt" -longest 586 | 587 | Returns the top 10 longest durations for all outgoing connections 588 | #> 589 | [CmdletBinding()] 590 | param( 591 | $file, 592 | [switch]$shortest, 593 | [switch]$longest 594 | ) 595 | $logs = get-content $file 596 | 597 | $obj = @() 598 | 599 | $obj = foreach($log in $logs){ 600 | $dur = '' 601 | $log = $log -split '\s+' 602 | $dataStart = $log[1]+' '+$log[2] 603 | $dataEnd = $log[3]+' '+$log[4] 604 | try{ 605 | $dataStart = [datetime]::ParseExact($dataStart,'dd-MM-yyyy HH:mm:ss', $null) 606 | } catch { } 607 | try{ 608 | $dataEnd = [datetime]::ParseExact($dataEnd,'dd-MM-yyyy HH:mm:ss', $null) 609 | } catch { } 610 | try{ 611 | $dur = New-TimeSpan -start $dataStart -end $dataEnd -ErrorAction SilentlyContinue 612 | [PSCustomObject]@{ 613 | IncomingID = $log[0] 614 | StartDate = $dataStart 615 | EndDate = $dataEnd 616 | Duration = [string]$dur.ToString("dd'd.'hh'h:'mm'm:'ss's'") 617 | LoggedOnUser = $log[5] 618 | ConnectionType = $log[6] 619 | ConnectionID = $log[7] 620 | } 621 | } catch { } 622 | } 623 | if($shortest){ 624 | $obj | Sort-Object Duration -Top 10 | Format-Table 625 | } 626 | if($longest){ 627 | $obj | Sort-Object Duration -Bottom 10 | Format-Table 628 | } 629 | } 630 | --------------------------------------------------------------------------------