none
Inaktive Benutzer mit Powershell finden RRS feed

  • 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

    Mittwoch, 6. Januar 2016 15:01

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.

    Donnerstag, 7. Januar 2016 10:13
    Moderator
  • 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



    Donnerstag, 7. Januar 2016 10:37
  • 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




    Donnerstag, 7. Januar 2016 12:22