An- und Abmelde Ereignisse mit Powershell auslesen
Hallo PS-Scriptler,
hat jemand von euch ein Script, der bestimmte User (z.B. administrator) in der Domain ausließt, welcher angibt wer sich zuletz auf welchem Server einlogged hat?
Mit Get-ADUser oder mit Get-ADcomputer bekomme ich aber nicht zusammen!
Vielen Dank!
Everest
hat jemand von euch ein Script, der bestimmte User (z.B. administrator) in der Domain ausließt, welcher angibt wer sich zuletz auf welchem Server einlogged hat?
Mit Get-ADUser oder mit Get-ADcomputer bekomme ich aber nicht zusammen!
Vielen Dank!
Everest
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 328713
Url: https://administrator.de/forum/an-und-abmelde-ereignisse-mit-powershell-auslesen-328713.html
Ausgedruckt am: 22.12.2024 um 11:12 Uhr
28 Kommentare
Neuester Kommentar
Servus @Everest,
habe ich mal einen PS-Workflow geschrieben der "parallel" alle erreichbaren Server der Domain abgrast und die Daten zusammenfasst. Die lassen sich dann nach Wunsch filtern:
(Achtung PS-Workflows gibt es erst ab PS 3.0, den ThrottleLimit Parameter erst ab v4)
Der Aufruf des Workflows geschieht in der letzten Zeile.
Der Workflow kennt ein paar Parameter zur grundlegenden Filterung:
-SamAccountName : Username mit Wildcardunterstützung, wenn weggelassen werden alle Logons gelistet
-MaxDays : Max. Anzahl an Tagen welche die Logon/Logoff Vorgänge in die Vergangenheit reichen sollen / Bei Nichtangabe 14 Tage.
-timeout: Ping-Timeout wenn ein Server als nicht erreichbar gelten soll
-ThrottleLimit : Anzahl an parallelen auszuführenden Threads. / Ohne Angabe 5 parallele Threads
Vorraussetzung ist natürlich das die Remote-Verwaltung bei den Servern in der Firewall aktiviert ist und diese per Ping erreichbar sind.
Und natürlich Auszuführen mit einem Account der auf allen Servern die entsprechenden Rechte besitzt.
Des weiteren müssen die An-/ und Abmelde-Events auch im Security-Eventlog geloggt werden, dazu muss vorher folgende Einstellung gesetzt werden (per GPO oder lokal) damit die EventIDs 4624 und 4647 im Security Eventlog geloggt werden:
Viel Spaß
Grüße Uwe
Falls der Beitrag gefällt, seid so nett und unterstützt mich durch eine kleine Spende / If you like my contribution please support me and donate
habe ich mal einen PS-Workflow geschrieben der "parallel" alle erreichbaren Server der Domain abgrast und die Daten zusammenfasst. Die lassen sich dann nach Wunsch filtern:
(Achtung PS-Workflows gibt es erst ab PS 3.0, den ThrottleLimit Parameter erst ab v4)
if ($PSVersionTable.PSVersion.Major -lt 4){write-host "ERROR: Minimum Powershell Version 4.0 is required!" -F Yellow; return}
Import-Module ActiveDirectory
workflow Get-LastLogonEvents {
param(
[parameter(mandatory=$false)][string]$SamAccountname = '*',
[parameter(mandatory=$false)][int]$MaxDays = 14,
[parameter(mandatory=$false)][int]$timeout = 500,
[parameter(mandatory=$false)][int]$throttlelimit = 5
)
function Send-Ping {
param([string]$device,[int]$delay)
$ping = New-Object System.Net.NetworkInformation.Ping
if($ping.Send($device,$delay).Status -ne "Success"){
return $false
}else{
return $true
}
}
function Get-Serverlogs([string]$server,$SamAccountname){
try{
if ((Send-Ping $server $timeout)){
Get-WinEvent -FilterXPath "*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and (EventID=4624)] and EventData[(Data[@Name='Logontype'] and (Data=2 or Data=10) and (Data[@Name='TargetDomainName'] != 'Window Manager' and Data[@Name='TargetDomainName'] != 'Font Driver Host' ))] or System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and (EventID=4647)]]" -LogName Security -ComputerName $server -EA Stop | ?{$_.TimeCreated -ge (get-date).AddDays(-$using:MaxDays)} | %{
$xml = [xml]$_.toXML()
$username = $xml.Event.EventData.Data | ?{$_.Name -eq 'TargetUserName'} | %{$_.'#text'}
if ($username -like $SamAccountname){
$ip = $xml.Event.EventData.Data | ?{$_.Name -eq 'IPAddress'} | %{$_.'#text'}
$type = $xml.Event.EventData.Data | ?{$_.Name -eq 'LogonType'} | %{$_.'#text'}
$logontype = @{"4647"="Logoff";"4624"=$(if($type -eq "10"){"Logon(Remote)"}else{"Logon"})}[$xml.Event.System.EventId]
[pscustomobject]@{Server=$server;UserName=$username;Time=$_.TimeCreated;LogonType=$logontype;IP=$ip}
}
}
}
}catch{}
}
# Fetch all computers with server operating system from AD
$servers = Get-ADComputer -Filter {Operatingsystem -like "*Server*"} | select -Expand DNSHostName
# initiate parallel workflow over all servers
foreach -parallel -throttlelimit $throttlelimit ($s in $servers){
# call function to fetch filtered security eventlog from server
Get-Serverlogs -server $s -SamAccountname $SamAccountname
}
}
Get-LastLogonEvents -MaxDays 90 -SamAccountName 'Administrator' | sort Time -Descending | ft Server,Username,Time,LogonType,IP -GroupBy Server
Der Workflow kennt ein paar Parameter zur grundlegenden Filterung:
-SamAccountName : Username mit Wildcardunterstützung, wenn weggelassen werden alle Logons gelistet
-MaxDays : Max. Anzahl an Tagen welche die Logon/Logoff Vorgänge in die Vergangenheit reichen sollen / Bei Nichtangabe 14 Tage.
-timeout: Ping-Timeout wenn ein Server als nicht erreichbar gelten soll
-ThrottleLimit : Anzahl an parallelen auszuführenden Threads. / Ohne Angabe 5 parallele Threads
Vorraussetzung ist natürlich das die Remote-Verwaltung bei den Servern in der Firewall aktiviert ist und diese per Ping erreichbar sind.
Und natürlich Auszuführen mit einem Account der auf allen Servern die entsprechenden Rechte besitzt.
Des weiteren müssen die An-/ und Abmelde-Events auch im Security-Eventlog geloggt werden, dazu muss vorher folgende Einstellung gesetzt werden (per GPO oder lokal) damit die EventIDs 4624 und 4647 im Security Eventlog geloggt werden:
Viel Spaß
Grüße Uwe
Falls der Beitrag gefällt, seid so nett und unterstützt mich durch eine kleine Spende / If you like my contribution please support me and donate
Zitat von @Everest:
es ist super, dass du dir Zeit genommen hast so ein Script zu schreiben. Danke Dir dafür.
Kein Problem ist schon länger her es ist super, dass du dir Zeit genommen hast so ein Script zu schreiben. Danke Dir dafür.
1) Zum Testen, kann ich anstatt:
$servers = Get-ADComputer -Filter testserver | select -Expand DNSHostName
nehmen?
Nein du musst hier im Filter die Filtereigenschaft angeben. Wenn du also auf einen bestimmten Server einschränken willst nimmst du$servers = Get-ADComputer -Filter testserver | select -Expand DNSHostName
nehmen?
$servers = Get-ADComputer -Filter {Name -eq "testserver"} | select -Expand DNSHostName
$servers = get-adcomputer -Filter * | ?{$_.Name -eq "testserver"} | select -Expand DNSHostName
2) ich habe PS v1 auf Windows Server 2008 Standard R2. Würde es auch gehen?
Nicht mit obigem Workflow, dazu muss man es grundlegend umschreiben oder auf min. PS 3.0 aktualisieren.Du kannst das Skript aber auch von jeder Verwaltungsstation mit aktueller Powershell und installiertem RSAT ausführen so musst du auf den Servern auch nicht zwingend was ändern.
Der Workflow hatte den einfachen Grund um den Vorgang einfach zu beschleunigen.
Die Hauptaufgabe erledigt ja wie du oben sehen kannst Zeile 22, die kannst du auch mit einer ganz einfachen Schleife über alle Server anwenden. Der Rest drum herum ist ja nur der Aufbau für die parallele Verarbeitung.
Alternative dazu wäre auch das zukünftige Einsammeln der Eventlogs auf einer zentralen Maschine dann entfällt das langwierige Abklappern aller Server.
Dort ist nichts falsch.
Du verwendest einfach entweder nicht mindestens PS 3.0 oder hast irgendwo eine Klammer zu viel gesetzt.
Skript läuft hier sowohl auf 2008R2 ADs als auch 2012-2022. Wenn es von "Verwaltungsstationen" ausgeführt wird ist ein installiertes RSAT mit AD-Tools natürlich zusätzlich Vorraussetzung.
Des weiteren müssen die An-/ und Abmelde-Events auch im Security-Eventlog geloggt werden, dazu muss vorher folgende Einstellung gesetzt werden (per GPO oder lokal) damit die EventIDs 4624 und 4647 im Security Eventlog geloggt werden:
Du verwendest einfach entweder nicht mindestens PS 3.0 oder hast irgendwo eine Klammer zu viel gesetzt.
Bei der Ausgabe wird den Lokal PC in Form IP ausgegeben? So dass man genauer lokalisieren kann von welchem PC aus hat dieser bestimmte User gestartet.
Wenn sich der User per Remote an diesem Server angemeldet hat wird in der Eigenschaft IP die Remote-IP des Clients vermerkt. Hat er sich lokal an der Konsole angemeldet steht dort die Loopback-Adresse oder ist leer.Skript läuft hier sowohl auf 2008R2 ADs als auch 2012-2022. Wenn es von "Verwaltungsstationen" ausgeführt wird ist ein installiertes RSAT mit AD-Tools natürlich zusätzlich Vorraussetzung.
Des weiteren müssen die An-/ und Abmelde-Events auch im Security-Eventlog geloggt werden, dazu muss vorher folgende Einstellung gesetzt werden (per GPO oder lokal) damit die EventIDs 4624 und 4647 im Security Eventlog geloggt werden:
Deine Powershell ist putt.
Gruß
Zitat von @Everest:
Was macht genau diese Zeile
foreach-parallel -throttle $throttlelimit ($s in $servers) {
Lesen: about_Foreach-ParallelWas macht genau diese Zeile
foreach-parallel -throttle $throttlelimit ($s in $servers) {
Gruß
Ach, ich hatte den Parameter -Throttle nicht ausgeschrieben sondern abgekürzt der sollte komplett -ThrottleLimit heißen. Workflows sind da sehr penibel dort wollen die Parameter vollständig ausgeschrieben werden. Die PS 3.0 war da noch etwas penibler die PS4 verzeiht das. Immer diese leidige Versions-Fragmentierung mit der Zeit, kaum lässt man sich auf den Komfort einer Nachfolgeversion ein tritt man in die Sch....
Freut mich das es dir hilft.
Viele Grüße
Uwe
Freut mich das es dir hilft.
Viele Grüße
Uwe
Servus,
Zitat:
Grüße Uwe
Zitat von @jan.kleinel:
das Skript ist sehr hilfreich, nur wie kann ich alle in der Domäne gespeicherten Benutzer anzeigen lassen.
Also Admin und alle anderen Benutzer gleichzeitig.
Steht oben unter dem Skript:das Skript ist sehr hilfreich, nur wie kann ich alle in der Domäne gespeicherten Benutzer anzeigen lassen.
Also Admin und alle anderen Benutzer gleichzeitig.
Zitat:
-SamAccountName : Username mit Wildcardunterstützung, wenn weggelassen werden alle Logons gelistet
Parameter weglassen, freuen Grüße Uwe
Zitat von @jan.kleinel:
Danke Uwe für die Antwort, habe das genau dann ausprobiert als du geantwortet hast :D
Na dann viel Spaß Danke Uwe für die Antwort, habe das genau dann ausprobiert als du geantwortet hast :D
Trozdem vielen Dank!
Immer gerne.Falls es dich vielleicht noch interessiert:
Anmeldestatus von Benutzern im Active Directory speichern
Servus.
Für persönliche Anpassungen, gerne per PN (kostenpflichtig).
Grüße Uwe
Zitat von @jan.kleinel:
könnte man das Ergebnis nicht theoretisch bei jedem starten in einem Textdokument speichern? Wenn ja wie wäre dieses möglich?
Hättest du den Thread aufmerksam gelesen dann hättest du gesehen das das Skript das per Remote schon aus den Rechnern ausliest, ein separates Ausführen auf jedem Client ist also unnötig. Die auszulesenden Rechner (im obigen Fall waren das ja nur die Server der Organisation) kannst du ja in der Zeile mit Get-AdComputer festlegen. Das Ergebnis kannst du am Ende einfach direkt an Export-CSV leiten und schon hast du deine gewünschte Datei die du nach Bedarf filtern kannst wie du lustig bist.könnte man das Ergebnis nicht theoretisch bei jedem starten in einem Textdokument speichern? Wenn ja wie wäre dieses möglich?
Für persönliche Anpassungen, gerne per PN (kostenpflichtig).
Grüße Uwe
Hallo Uwe,
ich würde gerne meine eigenen An- und Abmeldezeiten registrieren. Es handelt sich dabei um Domain Anmeldungen. Es gibt zwei DC.
Ich habe jetzt auf dem Primären DC Powershel von v1 auf v3 geupdatet. Powershel als Administrator geöffnet und dein Script unverändert per kopieren und einfügen eingefügt. Es wird leider nichts ausgegeben. Nach zweimaligen enter drücken, kommt folgende Fehlermeldungen. Wo liegt mein Fehler ? Throttlelimit scheint doch überall korrekt ausgeschrieben vorhanden.
Abspeichern als .ps und dann ausführen funktioniert auch nicht. Ausführung kann man kurz sehen, dann rote schrift und zu.
In Zeile:36 Zeichen:23
In Zeile:36 Zeichen:12
In Zeile:36 Zeichen:53
In Zeile:36 Zeichen:57
In Zeile:36 Zeichen:56
In Zeile:1 Zeichen:30
In Zeile:36 Zeichen:68
In Zeile:40 Zeichen:1
+ CategoryInfo : ParserError: ( , ParentContainsErrorRecordException
+ FullyQualifiedErrorId : InvalidForeachFlag
ich würde gerne meine eigenen An- und Abmeldezeiten registrieren. Es handelt sich dabei um Domain Anmeldungen. Es gibt zwei DC.
Ich habe jetzt auf dem Primären DC Powershel von v1 auf v3 geupdatet. Powershel als Administrator geöffnet und dein Script unverändert per kopieren und einfügen eingefügt. Es wird leider nichts ausgegeben. Nach zweimaligen enter drücken, kommt folgende Fehlermeldungen. Wo liegt mein Fehler ? Throttlelimit scheint doch überall korrekt ausgeschrieben vorhanden.
Abspeichern als .ps und dann ausführen funktioniert auch nicht. Ausführung kann man kurz sehen, dann rote schrift und zu.
}
Get-LastLogonEvents -MaxDays 90 -SamAccountName 'Administrator' | sort Time -Descending | ft Server,Us
Get-LastLogonEvents -MaxDays 90 -SamAccountName 'Administrator' | sort Time -Descending | ft Server,Us
foreach -parallel -throttlelimit $throttlelimit ($s in $servers){
~~~~~~~~~~~~~~
Der Parameter "throttlelimit" ist für die Anweisung "foreach" nicht zulässig.In Zeile:36 Zeichen:12
foreach -parallel -throttlelimit $throttlelimit ($s in $servers){
~
Öffnende "(" fehlt nach dem Schlüsselwort "foreach".In Zeile:36 Zeichen:53
foreach -parallel -throttlelimit $throttlelimit ($s in $servers){
~
Unerwartetes Token "(" in Ausdruck oder Anweisung.In Zeile:36 Zeichen:57
foreach -parallel -throttlelimit $throttlelimit ($s in $servers){
~~
Unerwartetes Token "in" in Ausdruck oder Anweisung.In Zeile:36 Zeichen:56
foreach -parallel -throttlelimit $throttlelimit ($s in $servers){
~
Schließende ")" fehlt in einem Ausdruck.In Zeile:1 Zeichen:30
workflow Get-LastLogonEvents {
~
Schließende "}" fehlt im Anweisungsblock.In Zeile:36 Zeichen:68
foreach -parallel -throttlelimit $throttlelimit ($s in $servers){
~
Unerwartetes Token ")" in Ausdruck oder Anweisung.In Zeile:40 Zeichen:1
}
~
Unerwartetes Token "}" in Ausdruck oder Anweisung.+ CategoryInfo : ParserError: ( , ParentContainsErrorRecordException
+ FullyQualifiedErrorId : InvalidForeachFlag
-ThrottleLimit benötigt min. PS V4
http://www.happysysadm.com/2013/06/how-to-throttle-workflow-activites-i ...
hauruck
http://www.happysysadm.com/2013/06/how-to-throttle-workflow-activites-i ...
hauruck
Zitat von @132895:
-ThrottleLimit benötigt min. PS V4
http://www.happysysadm.com/2013/06/how-to-throttle-workflow-activites-i ...
hauruck
Korrrekt. Hatte ich oben vergessen zu erwähnen, ist nachgeholt.-ThrottleLimit benötigt min. PS V4
http://www.happysysadm.com/2013/06/how-to-throttle-workflow-activites-i ...
hauruck
Hallo,
ich hab versucht das auszukommentieren, jedoch ohne Erfolg. Könnte mir jemand weiterhelfen, wie ich das Script für PS 3.0 anpasse und ggfs. auch einfach nur für einen Server und einen User. Danke.
ich hab versucht das auszukommentieren, jedoch ohne Erfolg. Könnte mir jemand weiterhelfen, wie ich das Script für PS 3.0 anpasse und ggfs. auch einfach nur für einen Server und einen User. Danke.
Windows PowerShell
Copyright (C) 2012 Microsoft Corporation. Alle Rechte vorbehalten.
PS C:\Users\######> if ($PSVersionTable.PSVersion.Major -lt 4){write-host "ERROR: Minimum Powershell Versio
n 4.0 is required!" -F Yellow; return}
ERROR: Minimum Powershell Version 4.0 is required!
PS C:\Users\#####> Import-Module ActiveDirectory
PS C:\Users\#####> workflow Get-LastLogonEvents {
>> param(
>> [parameter(mandatory=$false)][string]$SamAccountname = '*',
>> [parameter(mandatory=$false)][int]$MaxDays = 14,
>> [parameter(mandatory=$false)][int]$timeout = 500,
>> # [parameter(mandatory=$false)][int]$throttlelimit = 5
>> )
>>
In Zeile:5 Zeichen:54
+ [parameter(mandatory=$false)][int]$timeout = 500,
+ ~
Ausdruck nach "," fehlt.
In Zeile:1 Zeichen:30
+ workflow Get-LastLogonEvents {
+ ~
Schließende "}" fehlt im Anweisungsblock.
+ CategoryInfo : ParserError: (:) , ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MissingExpressionAfterToken
PS C:\Users\#####> function Send-Ping {
>> param([string]$device,[int]$delay)
>> $ping = New-Object System.Net.NetworkInformation.Ping
>> if($ping.Send($device,$delay).Status -ne "Success"){
>> return $false
>> }else{
>> return $true
>> }
>> }
>>
PS C:\Users\#####> function Get-Serverlogs([string]$server,$SamAccountname){
>> try{
>> if ((ping $server,$timeout)){
>> Get-WinEvent -FilterXPath "*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and (EventI
D=4624)] and EventData[(Data[@Name='Logontype'] and (Data=2 or Data=10) and Data[@Name='TargetDomainName'] != 'Window Ma
nager')] or System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and (EventID=4647)]]" -LogName Security -Comput
erName $server -EA Stop | ?{$_.TimeCreated -ge (get-date).AddDays(-$using:MaxDays)} | %{
>> $xml = [xml]$_.toXML()
>> $username = $xml.Event.EventData.Data | ?{$_.Name -eq 'TargetUserName'} | %{$_.'#text'}
>> if ($username -like $SamAccountname){
>> $ip = $xml.Event.EventData.Data | ?{$_.Name -eq 'IPAddress'} | %{$_.'#text'}
>> $type = $xml.Event.EventData.Data | ?{$_.Name -eq 'LogonType'} | %{$_.'#text'}
>> $logontype = @{"4647"="Logoff";"4624"=$(if($type -eq "10"){"Logon(Remote)"}else{"Logon"})}[$x
ml.Event.System.EventId]
>> [pscustomobject]@{Server=$server;UserName=$username;Time=$_.TimeCreated;LogonType=$logontype;
IP=$ip}
>> }
>> }
>> }
>> }catch{}
>> }
>> # Fetch all computers with server operating system from AD
>> $servers = Get-ADComputer -Filter {Operatingsystem -like "*Server*"} | select -Expand DNSHostName
>>
PS C:\Users\Administrator.#####> # initiate parallel workflow over all servers
PS C:\Users\Administrator.#####> # foreach -parallel -throttlelimit $throttlelimit ($s in $servers){
PS C:\Users\Administrator.#####> # call function to fetch filtered security eventlog from server
PS C:\Users\Administrator.#####> Get-Serverlogs -server $s -SamAccountname $SamAccountname
PS C:\Users\Administrator.#####> }
In Zeile:1 Zeichen:5
+ }
+ ~
Unerwartetes Token "}" in Ausdruck oder Anweisung.
+ CategoryInfo : ParserError: (:) , ParentContainsErrorRecordException
+ FullyQualifiedErrorId : UnexpectedToken
PS C:\Users\Administrator.#####> }
In Zeile:1 Zeichen:1
+ }
+ ~
Unerwartetes Token "}" in Ausdruck oder Anweisung.
+ CategoryInfo : ParserError: (:) , ParentContainsErrorRecordException
+ FullyQualifiedErrorId : UnexpectedToken
PS C:\Users\Administrator.#####> Get-LastLogonEvents -MaxDays 90 -SamAccountName 'Administrator' | sort Time -Descending
| ft Server,Username,Time,LogonType,IP -GroupBy Server
Junge du führst das einfach falsch aus, geht hier nämlich testweise absolut fehlerfrei!
Das pastet man nicht in die Konsole so wie du das hier machst. Für einen Server nehm dir doch einfach die Function aus dem Workflow raus . Man oh man, die Leute können echt nur noch copy n Paste ...
Das pastet man nicht in die Konsole so wie du das hier machst. Für einen Server nehm dir doch einfach die Function aus dem Workflow raus . Man oh man, die Leute können echt nur noch copy n Paste ...
Von PS Scripten habe ich wirklich keine Ahnung
Dann solltest du das erst mal ändern und dann wieder kommen. Man kann hier ja nicht jedem das "Fahren" beibringen . Mitdenken musst du schon, nimm nur die Function Get-ServerLogs die enthält ja alles was du brauchst, alles andere drum herum ist ja nur dafür da, viele Server gleichzeitig/parallel zu verarbeiten. Ohne minimal Hirn einschalten und sich grundlegend mit dem Inhalt zu beschäftigen wirst du mit Powershell nie warm!p.s. So ein schöner Thread durch deine Unwissenheit verunstaltet
Ob du es glaubs oder nicht, auch nur die Get Funktion habe ich per Konsole PS 3.0 versucht, ohne Erfolg.
Werde diesen Thread aber auch nicht weiter verunstalten und mich an deinen fachlichen Kommentaren erfreuen.
Cool, dann brauch ich bei euch nicht mehr zur Arbeit wenn ich die Kiste per Remote hoch und runter fahre :-P
Werde diesen Thread aber auch nicht weiter verunstalten und mich an deinen fachlichen Kommentaren erfreuen.
Cool, dann brauch ich bei euch nicht mehr zur Arbeit wenn ich die Kiste per Remote hoch und runter fahre :-P