Externe IP-Adresse eines RDP-Users ermitteln

Im Event-Log "Sicherheit" wird alles Eingetragen rund um das An-und Abmelden vom System. Dieses Eventlog kann per Powershell recht einfach ausgelesen werden. Das Skript benötigt allerdings Administrator-Rechte.

#----------------------------------------------------------------------------------------------
# Funktion(en)
#----------------------------------------------------------------------------------------------

Function GET-RDPLoginIPOfUser {
  <#
  .SYNOPSIS
  Prüft ob ein erfoglreiches Login vorkam und liefert die IP, Anmeldezeit und ob es ein Reconnect war zurück.
  .DESCRIPTION  
  Das Script durchsucht das Event-Log nach dem Vorkommen eines erfolgreichen RDP-Logins des Benutzers. Um die Suche schnell zu gestalten sollte das Skript direkt nach dem Login erfolgen.
  Die Eingrenzung der Suche nach "newest" ist ebenfalls deutlich schneller an nach "after".
  .EXAMPLE  
  GET-RDPLoginIPOfUser -newest '1000' 
  .EXAMPLE  
  GET-RDPLoginIPOfUser -newest '1000' -username 'loginname'
  .EXAMPLE  
  GET-RDPLoginIPOfUser -after $after   
  .PARAMETER hostname
  Es wird normalerweise der aktuelle Computer verwendet
  .PARAMETER username
  Um welchen Benutzer handelt es sich. Default ist es der aktuell angemeldete Benutzer 
  .PARAMETER newest
  Die letzten x Einträge im Security-Log nach dem Benutzer durchsuchen. Wenn das Skript direkt nachdem Login erfolgt müsste 5 ausreichen.
  .PARAMETER After
  Das Security-Log über einen bestimmten Zeitraum durchsuchen. Wenn nach den letzten Ereignissen der letzten 2 Minuten gesucht werden soll z.B $after = (Get-Date).AddMinutes(-2)  
  #>
  
  [CmdletBinding()]
  Param (
    [Parameter(Mandatory=$false,Position=0)]
    [String]$hostname=$Env:COMPUTERNAME,
    [Parameter(Mandatory=$false,Position=1)]
    [String]$username=$Env:USERNAME.ToLower(),
    [Parameter(Mandatory=$false,Position=2)]
    [String]$newest='5',
    [Parameter(Mandatory=$false,Position=3)]
    [Datetime]$After
  )

  Set-Variable kn -option Constant -value 'Kontoname:'  
  Set-Variable qna -option Constant -value 'Quellnetzwerkadresse:'
  Set-Variable ca -option Constant  -value 'Clientadresse:'
  $ip = '' 

  # 4624 -&gt; "Ein Konto wurde erfolgreich angemeldet.", 4778 -&gt; "Eine Sitzung wurde erneut mit einer Arbeitsstation verbunden."
  if ([string]::IsNullOrEmpty($after)) {
    $events = get-eventlog security -InstanceID 4624,4778 -ComputerName $hostname -newest $newest
  } else {
    $events = get-eventlog security -InstanceID 4624,4778 -ComputerName $hostname  -After $After
  }

  # Die einizelnen Ereignisse durchlaufen
  foreach($event in $events) {  
    # In Message steht alles
    $Message = $event.Message
    $arrMessage = ($Message -split "`n").Trim()
  
    $match = ($arrMessage -match $kn).replace($kn, '').Trim()
    foreach ($s in $match) {
      if ($s.ToLower() -eq $username) {
        $ip = $arrMessage -match $qna #Login
        if ([string]::IsNullOrEmpty($ip)) {$ip = $arrMessage -match $ca} #Relogin
        if ([string]::IsNullOrEmpty($ip)) {
        } elseif ($ip -eq '-') {
          $ip = ''
        } else {
          if ($ip.indexof($qna) -gt 0) {$login = 'loging'} else {$login = 'relogin'}
          $ip = $ip.replace($qna, '').replace($ca, '').Trim()
          #$time = $event.TIMEGENERATED
          $time = $event.TimeWritten.tostring("MM.dd.yyyy HH:MM:SS")                 
          break 
        }
      }
    }        
    if ($ip -ne '') {break}  # Es wurde eine IP ermittelt somit die Schleife(n) verlassen                        
  }  
  if ($ip -ne '') {
      # Rückgabe als Array  
      $return = @($username, $ip, $time, $login)    
      # Rückgabe als HashTable
      <#
      $return = @{}
      $return.username = $username
      $return.ip = $ip
      $return.time = $time
      $return.$login = $login
      #>
      $return
  }
}    
#----------------------------------------------------------------------------------------------
# Skript 
#----------------------------------------------------------------------------------------------
$userinfo = GET-RDPLoginIPOfUser -newest 100
if (!([string]::IsNullOrEmpty($userinfo))) {
  $userinfo[0]
  $userinfo[1]
  $userinfo[2]
  $userinfo[3]
}
$after = (Get-Date).AddMinutes(-10) 
$userinfo = GET-RDPLoginIPOfUser -After $after
if (!([string]::IsNullOrEmpty($userinfo))) {
  $userinfo[0]
  $userinfo[1]
  $userinfo[2]
  $userinfo[3]
}