none
.txt file filtern und speichern RRS feed

  • Frage

  • Hallo Powershell Profis,

    Ich habe wöchentlich ein textfile mit gelockten Windows Accounts und würde dieses gerne manipulieren und abspeichern.
    Hier ein Beispiel, damit ihr euch etwas darunter vorstellen könnt:

    TimeGenerated,EventID,EventTypeName,Message
    2012-11-21 16:03:36,644,Success Audit event,"User Account Locked Out: Target Account Name: xx Target Account ID: xx Caller Machine Name: xx Caller User Name: xx Caller Domain: xx Caller Logon ID: (0x0,0x3E7) "
    TimeGenerated,EventID,EventTypeName,Message
    2012-11-21 16:03:36,644,Success Audit event,"User Account Locked Out: Target Account Name: xx Target Account ID: xx Caller Machine Name: xx Caller User Name: xx Caller Domain: xx Caller Logon ID: (0x0,0x3E7) "
    TimeGenerated,EventID,EventTypeName,Message
    2012-12-03 09:29:48,644,Success Audit event,"User Account Locked Out: Target Account Name: xx Target Account ID: xx Caller Machine Name: xx Caller User Name: xx Caller Domain: xx Caller Logon ID: (0x0,0x3E7) "
    TimeGenerated,EventID,EventTypeName,Message
    2012-12-05 21:00:06,644,Success Audit event,"User Account Locked Out: Target Account Name: xx Target Account ID: xx Caller Machine Name: xx Caller User Name: xx Caller Domain: xx Caller Logon ID: (0x0,0x3E7) "
    TimeGenerated,EventID,EventTypeName,Message
    2012-12-05 21:00:06,644,Success Audit event,"User Account Locked Out: Target Account Name: xx Target Account ID: xx Caller Machine Name: xx Caller User Name: xx Caller Domain: xx Caller Logon ID: (0x0,0x3E7) "
    TimeGenerated,EventID,EventTypeName,Message
    2012-12-06 15:05:19,644,Success Audit event,"User Account Locked Out: Target Account Name: xx Target Account ID: xx Caller Machine Name: xx Caller User Name: xx Caller Domain: xx Caller Logon ID: (0x0,0x3E7) "

    Ich möchte nun die Zeilen, mit Informationen der letzen 8 Tage, filtern und in eine neue Textdatei schreiben und abspeichern.

    Ich habe mir gedacht, man könnte Variablen definieren:

    $Datum = $Date = Get-Date -Format yyyy-MM-dd

    $old_Datum =  ((get-date).AddDays(-7)) -Format yyyy-MM-dd

    dann eine Schleife bauen, die jede 2. Zeile des Dokumentes abarbeitet und prüft, ob das Datum am Zeilenanfang > oder < als $old_Datum ist. Wenn kleiner, dann nächste Zeile, wenn größer, dann die Zeile in ein neues Textdokument schreiben.

    Oder man könnte vielleicht get-string in einer Schleife benutzen?
    In Java wäre das denke ich:

    for (int i = 0, i<8 , i ++){
      $Datum_temp = ((get-date).AddDays(-i)) 
      Select-String -Simple $Datum_temp lockout.txt
    }

    Könnt ihr mir sagen wie ich das möglichst schön in powershell machen kann?

    Danke und Gruß

    Chris

    Dienstag, 11. Dezember 2012 10:22

Antworten

  • Raimund seine Lösung Funktioniert bei mir nicht, da Die Datei keine CSV Datei ist!

    Bei der Lösung von Schlieng kann ich nicht erkennen, dass das Datum von Heute ermittelt wird und der Code somit dynamisch ist.

    Bei Maschinell erstellten Daten kann man sich zwar meist darauf verlassen das nicht "ausversehen" mal eine Leerzeile oder etwas ähnliches dazwischenkommt, aber ich bin kein Fan von abzählen!

    Daten kannst du anhand von Daten erkennen und nicht anhand von Zeilen Zählen!

    All deine Zeilen die dich Interessieren fangen mit dem Jahr oder dem Datum an! Deshalb ist es besser diesen Zeilenanfang zu nutzen.

    Im ersten Schritt lasse ich nur Zeilen durch, die mit dem Datumsformat anfangen.

    Get-Content 'C:\temp\test.txt' | Where-Object { $_ -match "^\d\d\d\d-\d\d-\d\d"}

    Da ich nun sicher weiß das ich nur Zeilen haben die mit einem Datum anfangen kann ich die ersten Zeichen der Zeile in ein DateTime Objekt wandeln lassen.

    Get-Content 'C:\temp\test.txt' | Where-Object { $_ -match "^\d\d\d\d-\d\d-\d\d"} | ForEach-Object {
        [DateTime]$_.substring(0,10)
     }

    Jetzt brauche ich nur noch zu prüfen ob das Datum grösser ist als das Datum vor 8 Tagen

    $OldDate = (get-date).AddDays(-7)
    
    Get-Content 'C:\temp\test.txt' | Where-Object { $_ -match "^\d\d\d\d-\d\d-\d\d"} | ForEach-Object {
          
        IF ([DateTime]$_.substring(0,10) -ge $OldDate) {
            # Das Datum der Zeile liegt in den letzten 8 Tagen
            # Die Zeile wird ausgegeben
            $_
        }
        
    } | Out-File 'C:\temp\test1.txt' # ausgabe der gesuchten Zeillen in eine Datei

    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!

    • Als Antwort markiert Chris Traveler Mittwoch, 12. Dezember 2012 16:15
    Mittwoch, 12. Dezember 2012 15:42

Alle Antworten

  • Hallo,

    so könnte das Filtern nach Datum gehen:

     

    Import-Csv '.\new  1.txt' | Where-Object { [DateTime]$_.TimeGenerated -gt (Get-Date).AddDays(-8) }

    Das Resultat könnte wieder über Export-Csv in eine neue Datei geschrieben werden.

     


    -Raimund




    Dienstag, 11. Dezember 2012 20:36
  • Hallo,

    du könntest auch über RegEx in jeder Zeile das Datum ermitteln und mit $old_Datum vergleichen, und wenn das Datum das gleiche bzw. Jünger ist, schreibst du diese Zeile in eine neue Datei

    $regex = [RegEx]"^[0-9]{4}-(((0[13578]|(10|12))-(0[1-9]|[1-2][0-9]|3[0-1]))|(02-(0[1-9]|[1-2][0-9]))|((0[469]|11)-(0[1-9]|[1-2][0-9]|30)))"
    $old_Datum = (Get-Date).AddDays(-7).ToString('yyyy-MM-dd')
    Get-Content C:\Temp\test.txt | ForEach-Object {
    	IF ( $regex.Match($_).Value -ge $old_Datum ) {
    		$_ | Out-File C:\Temp\Out-File.txt -Append
    	}
    }

    MfG
    Mittwoch, 12. Dezember 2012 14:44
  • Raimund seine Lösung Funktioniert bei mir nicht, da Die Datei keine CSV Datei ist!

    Bei der Lösung von Schlieng kann ich nicht erkennen, dass das Datum von Heute ermittelt wird und der Code somit dynamisch ist.

    Bei Maschinell erstellten Daten kann man sich zwar meist darauf verlassen das nicht "ausversehen" mal eine Leerzeile oder etwas ähnliches dazwischenkommt, aber ich bin kein Fan von abzählen!

    Daten kannst du anhand von Daten erkennen und nicht anhand von Zeilen Zählen!

    All deine Zeilen die dich Interessieren fangen mit dem Jahr oder dem Datum an! Deshalb ist es besser diesen Zeilenanfang zu nutzen.

    Im ersten Schritt lasse ich nur Zeilen durch, die mit dem Datumsformat anfangen.

    Get-Content 'C:\temp\test.txt' | Where-Object { $_ -match "^\d\d\d\d-\d\d-\d\d"}

    Da ich nun sicher weiß das ich nur Zeilen haben die mit einem Datum anfangen kann ich die ersten Zeichen der Zeile in ein DateTime Objekt wandeln lassen.

    Get-Content 'C:\temp\test.txt' | Where-Object { $_ -match "^\d\d\d\d-\d\d-\d\d"} | ForEach-Object {
        [DateTime]$_.substring(0,10)
     }

    Jetzt brauche ich nur noch zu prüfen ob das Datum grösser ist als das Datum vor 8 Tagen

    $OldDate = (get-date).AddDays(-7)
    
    Get-Content 'C:\temp\test.txt' | Where-Object { $_ -match "^\d\d\d\d-\d\d-\d\d"} | ForEach-Object {
          
        IF ([DateTime]$_.substring(0,10) -ge $OldDate) {
            # Das Datum der Zeile liegt in den letzten 8 Tagen
            # Die Zeile wird ausgegeben
            $_
        }
        
    } | Out-File 'C:\temp\test1.txt' # ausgabe der gesuchten Zeillen in eine Datei

    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!

    • Als Antwort markiert Chris Traveler Mittwoch, 12. Dezember 2012 16:15
    Mittwoch, 12. Dezember 2012 15:42
  • Hallo,

    zunächst einmal Danke für die Hilfe.

    Raimund, deine Lösung hat bei mir leider nicht funktioniert.

    Schlieng, deine Lösung hat zwar gefiltert, allerdings wurden zu viele Ergebnisse zurückgeliefert.

    Peter, deine Lösung macht genau das was ich möchte - Vielen Dank!

    Gruß

    Chris

    Mittwoch, 12. Dezember 2012 16:15
  • Eine Csv Datei ist durch ein Trennzeichen getrennt. Das ist hier sehr wohl der Fall und der Umstand sollte genutzt werden. Es ist IMHO immer besser, mit strukturierten Daten zu arbeiten und diese dann auch via Import-Csv zu nutzen. Der zweite Vorschlag geht sehr wohl von dem aktuellen Datum aus, das hast Du wohl überlesen.
    Mittwoch, 12. Dezember 2012 22:33
  • @Raimund
    Du reduzierst das CSV Format darauf, das es Trennzeichen separierte Werte sind! Das wird dem CSV Format nicht gerecht!
    siehe Wikipedia und RFC 4180!http://de.wikipedia.org/wiki/CSV_%28Dateiformat%29

    http://tools.ietf.org/html/rfc4180

    Der erste Datensatz kann ein Kopfdatensatz sein, der die Spaltennamen definiert

    Hier besteht aber jede 2. Zeile aus Kopfdaten und jede 2. Zeile aus den echten Daten. Das ist KEIN CSV Format!

    Import-CSV interpretiert das CSV Format genau so, deshalb Funktioniert es bei mir und auch bei Chris nicht!
    Hast du deinen Code mit den Daten von Chris als echte .TXT Datei getestet?

    In dem Regex von Schlieng  wird NICHT das Datum von Heute ermittelt! Deshalb kann der Code von Schlieng NICHT die letzten 8 Tage von Heute heraus filtern. Der Code geht statisch von einem Anfangsdatum aus und nicht Dynamisch von dem Aktuellen Datum (Heute) !
    Deshalb entspricht auch dieser Code nicht den Anforderungen!

    Wer ist eigentlich JSpieler ?


    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!

    Donnerstag, 13. Dezember 2012 06:42
  • Die Daten sind schon CSV, nur ist die Ausgabe nicht der Norm entsprechend. Man sollte das Eingabeformat optimieren, bevor man die gesamte Automation sehr ungünstigen Daten anpaßt. Das hätte hier vielleicht hinterfragt werden sollen.

     

    Das wird leider viel zu häufig nicht gemacht. Es wird dann versucht, ineffiziente Prozesse oder redundante Daten abzugleichen, ohne das Problem an der Wurzel zu fassen.


    -Raimund

    Donnerstag, 13. Dezember 2012 16:37
  • @Raimund

    Da bin ich komplett bei dir!
    Ich habe ja auch in meinem Post geschrieben das man möglichst immer mit Daten (Objekten) Arbeiten sollte und nicht mit Text oder abzählen.

    Das würde hier aber den zwischen Schritt des Daten Umformatierens verlangen. Für PowerShell würde dies bedeuten man erzeugt einen Temporäre CSV Datei oder man muss sich PowerShell (untypisch) mit den .NET Stream Klassen herumschlagen um das ganze im Speicher abzuwickeln.

    Ich zumindest, habe den Anspruch, dass man in der PowerShell auch ohne .NET Programmierkenntnisse auskommen sollte.


    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!

    Freitag, 14. Dezember 2012 06:49