Fragensteller
Inaktive Benutzer mit Powershell finden

Allgemeine Diskussion
-
Hallo zusammen,
ich habe einen Skript erstellt, zum finden von inaktiven Benutzern. Er ist ausführlich kommentiert und selbsterklärend. Vielleicht hilft es dem ein oder anderen.
Aktuell weist der Skript eine schlechte Performance auf, für Optimierungsvorschläge aller Art bin ich offen!
<# .SYNOPSIS Inaktive Benutzer auf allen DCs finden .DESCRIPTION Dieser Skript sucht anhand des Attributs LastLogonTimestamp alle inaktiven Benutzer innerhalb einer Domäne. Dabei werden alle Domain Controller geprüft. Zudem können deaktiverte Benutzer ausgeschlossen werden und ein Zeitraum gefiltert werden. .PARAMETER <Parameter_Name> $dcs (array)= Alle Domain Controller der Domäne $i (long)= Zähler für erfasste Benutzer $userscope (string) = Umfang der zu prüfenden Benutzer $username (array)= Array der Benutzer $timefilter (date)= Alter des LastLogonTimestamps $time (date)= LastLogonTimestamp-Attribut $filename (string)= Dateiname $file (string)= Dateipfad $hostname (string)= Hostname des Domain Controllers $SamAccountName (string)= SamAccountName des Benutzers $Enabled (boolean)= Enabled Attribut des Benutzers $FoundUsers (string) = Ausgabe für Zähler $i .INPUTS Nur aktive Benuzter oder alle Benutzer, Alter des LastLogonTimestamps, Dateiname .OUTPUTS Ausgabedatei als CSV, Pfad der Ausgabedatei, Information über gelesene Attribute, Anzahl der gefundenen Benutzer .NOTES Version: 1.0 Author: Malte B. Creation Date: 06.01.2016 Purpose/Change: Initial script development .EXAMPLE #> #---------------------------------------------------------[Initialisations]----------------------------------------------------- # Importieren des AD PS Moduls Import-Module ActiveDirectory #----------------------------------------------------------[Declarations]---------------------------------------------------------- # Auslesen alles DCs in der Domäne $dcs = Get-ADDomainController -Filter {Name -like "*"} # Zählervariable definieren $i = 0 # Abfragen ob nur aktive Benutzer oder alle Benutzer berücksichtigt werden sollen $userscope = Read-Host 'Sollen nur aktive Benutzer abgefragt werden? Ja[J,Y] Nein[N]' # Bedienung prüft ob "Nein" geantwortet wurde If ($userscope -eq "N" -eq "n" -eq "Nein" -eq "nein" -eq "No" -eq "no"){ # Kein Benutzer wird gefiltert $username = Get-ADUser -F * # Andere Antwort als "Nein" } else { # Filter auf das Attribut "Enabled = true" $username = Get-ADUser -F {Enabled -eq "true"}} # Abfrage wie lang das letzte Logon-Date das Benutzers her sein soll $timefilter = Read-Host 'Nur Benutzer auslesen, die sich länger als angebene Tage nicht angemeldet haben. Nur Zahlenwert, 0 erfasst alle' # Errechnung des Datums vor dem die letzte Anmeldung durchgeführt wurde $timefilter = (Get-Date).Adddays(-($timefilter)) # Dateinamen angeben $filename = Read-Host 'Dateiname' # Generierung des Speicherpfads $path = ".\" + $filename + ".csv" #-----------------------------------------------------------[Execution]------------------------------------------------------------ # Wenn die Datei bereits existiert, wird diese gelöscht und neu angelegt. Dies wird mit einer Ausgabe kommentiert If (Test-Path $path){ Remove-Item $path echo "Datei unter diesem Namen schon vorhanden, die Datei wird überschrieben!" } # Erste Zeile der Ausgabedatei/Title der Spalten "SamAccountName" +";" + "Enabled" + ";" + "Time">> $path # Schleife geht alle Benutzer durch foreach($User in $username) { # Zeit initial auf 0 gesetzt $time = 0 # Schleife geht alle DCs durch foreach($dc in $dcs) { # Auslesen des DC-Hostnames $hostname = $dc.HostName # Auslesen des letzten lastLogonTimestamps des Benutzers auf einem DC $user = Get-ADUser $User -Server $hostname | Get-ADObject -Properties lastLogonTimestamp # Ist der lastlogonTimestamp auf einem anderen DC größer, wird dieser Wert genommen. Initial ist time=0, daher wird der erste Wert immer gespeichert if($user.lastLogonTimestamp -gt $time) { # Speichern des lastLogonTimestamps $time = $user.lastLogonTimestamp } } # Formatierung des lastLogonTimestamp-Wertes $time = [datetime]::FromFileTime($time) # Nur wenn der lastLogonTimestamp kleiner als der Filterwert ist, werden die Daten in die Datei geschrieben If ($time -lt $timefilter){ # Auslesen des SamAccountNames $SamAccountName = Get-ADUser $User -P SamAccountName $SamAccountName = $SamAccountName.SamAccountName # Auslesen des Enabled-Attributs $Enabled = Get-ADUser $User -P Enabled $Enabled = $Enabled.Enabled # Übergeben der Daten in die Ausgabedatei $SamAccountName + ";" + $Enabled + ";" + $time >> $path # Zählerwert hochsetzen $i++} } # Diverse Ausgaben: #Auslesen der Skript-Pfades und Ausgabe des Speicherorts der Ausgabedatei $path = Get-Location $path = $path.ToString() + "\" + $filename + ".csv" $path = "Ausgabe wurde gespeichert unter " + $path + "." echo $path #Information echo "Gesucht wurde nach den Attributen SamAccountName, Enabled und LastlogonTimestamp." #Ausgabe des Zählerwertes $FoundUsers = "Es wurden " + $i + " Benutzer gefunden." echo $FoundUsers
Viele Grüße
Malte
Alle Antworten
-
Hallo Malte,
vielen Dank für das Script, es wird bestimmt für mehrere Leute nützlich sein.
Gruß,
Teodora
Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „IT-Pros helfen IT-Pros“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.
-
Hallo Malte,
danke für dein Skript.
kleine Anmerkung:
in den Zeilen 98-104 fragst du jedes mal das AD neu ab. Diese Infos stehen allerdings bereits in der $User Variable!
Du kannst also einfach:
# Auslesen des SamAccountNames $SamAccountName = $User.SamAccountName # Auslesen des Enabled-Attributs $Enabled = $User.Enabled
Du musst den Teil dann nur vor deine LogonTimeStamp Schleife setzen.
Das sollte das Skript schon mal beschleuinigen.
PS: nicht echo sondern Write-Host ;-)
Beste Grüße
Eric
Microsoft MVP Cloud and Datacenter Management
Microsoft Partner Technical Solutions Professional (P-TSP)
--
www.ericberg.de
@ericberg_de
--
MCSE: Enterprise Decives and Apps | MCSE: Private Cloud | MCSE: Server Infrastructure | MCSE: Desktop Infrastructure
- Bearbeitet Eric Berg [MVP]MVP Donnerstag, 7. Januar 2016 10:49
-
Hallo Malte,
ich hab mal etwas gebastelt. Schaus dir mal an:
<# .SYNOPSIS Inaktive Benutzer auf allen DCs finden .DESCRIPTION Dieser Skript sucht anhand des Attributs LastLogonTimestamp alle inaktiven Benutzer innerhalb einer Domäne. Dabei werden alle Domain Controller geprüft. Zudem können deaktiverte Benutzer ausgeschlossen werden und ein Zeitraum gefiltert werden. .PARAMETER OnlyActiveUsers Angabe ob nur aktive oder auf inaktive User abgefragt werden sollen .PARAMETER DaysSinceLogon Tage seit dem letzten Logon .PARAMETER LogPath Pfad zur Ausgabedatei (CSV) .INPUTS Nur aktive Benuzter oder alle Benutzer, Alter des LastLogonTimestamps, Dateiname .OUTPUTS Ausgabedatei als CSV, Pfad der Ausgabedatei, Information über gelesene Attribute, Anzahl der gefundenen Benutzer .NOTES Version: 1.0 Author: Malte B. Creation Date: 06.01.2016 Purpose/Change: Initial script development .EXAMPLE .\Get-LastLogon.ps1 -OnlyActiveUsers $True -DaysSinceLastLogon 30 -LogPath "C:\ausgabe.csv" #> [CmdletBinding()] Param( [Boolean]$OnlyActiveUsers = $True, [Parameter(Mandatory=$True)] [int]$DaysSinceLastLogon, [Parameter(Mandatory=$True)] [string]$LogPath ) #---------------------------------------------------------[Initialisations]----------------------------------------------------- # Importieren des AD PS Moduls Import-Module ActiveDirectory #----------------------------------------------------------[Declarations]---------------------------------------------------------- # Auslesen aller DCs in der Domäne $dcs = Get-ADDomainController -Filter {Name -like "*"} # Zählervariable definieren $i = 0 # Nur aktive oder alle User Abfragen if ($OnlyActiveUsers -eq $False) { $AllUsers = Get-ADUser -Filter {Enabled -eq "true"} } else { $AllUsers = Get-ADUser -Filter * } # Zeitfilter bestimmen $timefilter = (Get-Date).Adddays(-($DaysSinceLastLogon)) #-----------------------------------------------------------[Execution]------------------------------------------------------------ # Wenn die Datei bereits existiert, wird diese gelöscht und neu angelegt. Dies wird mit einer Ausgabe kommentiert If (Test-Path $LogPath){ Remove-Item $LogPath Write-Host "Datei unter diesem Namen schon vorhanden, die Datei wird überschrieben!" } # Erste Zeile der Ausgabedatei/Title der Spalten "SamAccountName" +";" + "Enabled" + ";" + "Time">> $Logpath # Schleife geht alle Benutzer durch foreach($User in $AllUSers) { # Zeit initial auf 0 gesetzt $time = 0 # Auslesen des SamAccountNames $SamAccountName = $User.SamAccountName # Auslesen des Enabled-Attributs $Enabled = $User.Enabled # Schleife geht alle DCs durch foreach($dc in $dcs) { # Auslesen des DC-Hostnames $hostname = $dc.HostName # Auslesen des letzten lastLogonTimestamps des Benutzers auf einem DC $user = Get-ADUser $User -Server $hostname | Get-ADObject -Properties lastLogonTimestamp # Ist der lastlogonTimestamp auf einem anderen DC größer, wird dieser Wert genommen. Initial ist time=0, daher wird der erste Wert immer gespeichert if($user.lastLogonTimestamp -gt $time) { # Speichern des lastLogonTimestamps $time = $user.lastLogonTimestamp } } # Formatierung des lastLogonTimestamp-Wertes $time = [datetime]::FromFileTime($time) # Nur wenn der lastLogonTimestamp kleiner als der Filterwert ist, werden die Daten in die Datei geschrieben If ($time -lt $timefilter){ # Übergeben der Daten in die Ausgabedatei $SamAccountName + ";" + $Enabled + ";" + $time >> $LogPath # Zählerwert hochsetzen $i++} } # Diverse Ausgaben: #Auslesen der Skript-Pfades und Ausgabe des Speicherorts der Ausgabedatei Write-Host = "Ausgabe wurde gespeichert unter $LogPath." #Information Write-Host "Gesucht wurde nach den Attributen SamAccountName, Enabled und LastlogonTimestamp." #Ausgabe des Zählerwertes Write-Host "Es wurden $i Benutzer gefunden."
Beste Grüße
Eric
Microsoft MVP Cloud and Datacenter Management
Microsoft Partner Technical Solutions Professional (P-TSP)
--
www.ericberg.de
@ericberg_de
--
MCSE: Enterprise Devices and Apps | MCSE: Private Cloud | MCSE: Server Infrastructure | MCSE: Desktop Infrastructure
- Bearbeitet Eric Berg [MVP]MVP Donnerstag, 7. Januar 2016 12:32