2016-12-14 1 views
-3

Ich habe eine Textdatei, die Daten aus einem PowerShell-Skript enthält. Die Daten sind der Status von BitLocker auf Domänen-Laptops. Ein Beispiel dafür, was die Textdatei enthält, ist wie folgt:Skript, um Muster in mehreren Zeilen zu finden und echo Computername, der Muster entspricht

Computer Name:  Computer1 
Conversion Status: Fully Encrypted 
Protection Status: Protection On 
Computer Name:  Computer2 
Conversion Status: Fully Encrypted 
Protection Status: Protection Off 
Computer Name:  Computer3 
Conversion Status: Fully Decrypted 
Protection Status: Protection Off 
Conversion Status: Fully Encrypted 
Protection Status: Protection On 

Was ich suche ist ein Skript, das für alle Fälle, in denen zwei bestimmte Linien liegen nebeneinander suchen. Also zum Beispiel in der Textdatei, ich brauche das Skript um zu finden, wo die Zeilen "Conversion Status: Fully Encrypted" und "Protection Status: Protection Off" sind. Sobald diese Anforderung erfüllt ist, muss der Name des Computers, der über diesen beiden Zeilen liegt, in einer Textdatei wiedergegeben oder weitergeleitet werden. Im obigen Beispiel wäre es Computer2. Zu beachten ist, dass einige Systeme mehrere Festplattenlaufwerke oder Partitionen mit separaten BitLocker-Status haben. So ein System kann zwei Einträge in der Textdatei wie Computer3 in meinem obigen Beispiel haben.

Das Endergebnis, das ich möchte, ist eine Textdatei, die nur die Computernamen enthält, die den Status "Conversion Status: Fully Encrypted" und "Protection Status: Protection Off" haben. Ich bin ziemlich eingeschränkt in meinen Skriptfähigkeiten, bin aber in der Lage, diese Dinge herauszufinden. Dieser hat mich ebenso wie die anderen Admins, mit denen ich arbeite, ratlos. Jede Hilfe oder Richtung würde geschätzt werden.

+2

Lassen Sie das PowerShell-Skript die Daten als CSV- statt als Listenformat exportieren, und verwenden Sie einfach 'findstr'. –

+0

Mit einer CSV-Datei verwende ich sehr gerne die einfache [Filterung] (https://www.timeatlas.com/excel-autofilter/) in Excel/Google Tabellen, wenn Sie sich die Daten ansehen, während Sie Ihre Ausgabe schön visualisieren. –

+0

Mögliche Duplikate von [Lesen einer Textdatei Zeile für Zeile in einem Batch oder VBS-Skript?] (Http://Stackoverflow.com/q/1065517/692942) – Lankymart

Antwort

0

Wenn Sie Zeile für Zeile durch eine Datei arbeiten und je nach Inhalt von mehr als einer Zeile eine Aktion ausführen möchten, müssen Sie den Status der zuvor gesehenen Zeilen speichern. Um den möglicherweise komplizierten booleschen Ausdruck zu bewerten (gesehen dies oder das, aber nicht das ...), ist ein Select Case True/False nützlich.

Demo-Code:

Option Explicit 

Function qq(s) : qq = """" & s & """" : End Function 

Dim oFS : Set oFS = CreateObject("Scripting.FileSystemObject") 
Dim oTS : Set oTS = oFS.OpenTextFile("..\data\41145072.txt") 
Dim sLine, aParts, sKey, sVal, sCom, sCon, sProt 
Do Until oTS.AtEndOfStream 
    sLine = oTS.ReadLine() 
    aParts = Split(sLine, ":") 
    If 1 = UBound(aParts) Then 
     sKey = Left(sLine, 3) 
     sVal = Trim(aParts(1)) 
'  WScript.Echo qq(sLine), qq(sVal) 
     Select Case True 
      Case sKey = "Com" 
      sCom = sVal 
      Case sKey = "Con" 
      sCon = sVal 
      Case sKey = "Pro" And sCon = "Fully Encrypted" And sVal = "Protection Off" 
      WScript.Echo "****", sCom, sCon, sVal 
     End Select 
    Else 
     WScript.Echo oTS.Line, qq(sLine), "Parse Error" 
    End If 
Loop 
oTS.Close 

Ausgang:

cscript 41145072.vbs 
**** Computer2 Fully Encrypted Protection Off 
+0

Laden Sie stundenweise auf? – Lankymart

+0

Nur eine Variation einer [vorhandenen Antwort] (http://stackoverflow.com/a/1065589/692942). – Lankymart

+1

Ich finde immer diese Syntax '1 = UBound (aParts)' so verwirrend, Werte werden mit der Variablen auf der linken Seite und der Zuweisung auf der rechten Seite gesetzt. Warum schalte ich das bei einem Vergleich um ?, schimpft einfach auf mich - * Entschuldigung *. – Lankymart

1

Ich beantworte keine Fragen verwendet, die zeigen keine Mühe aus dem OP; Dieses Problem ist jedoch ziemlich interessant!

@echo off 
setlocal EnableDelayedExpansion 

for /F "delims=" %%a in (input.txt) do (
    set "line=%%a" 
    for /F "tokens=1,2 delims=:" %%b in ("!line: =!") do (
     if "%%b" equ "ComputerName" set "ConversionStatus=" 
     if "%%b" equ "ConversionStatus" set "ProtectionStatus=" 
     set "%%b=%%c" 
    ) 
    if "!ConversionStatus!+!ProtectionStatus!" equ "FullyEncrypted+ProtectionOff" (
     echo !ComputerName! 
    ) 
) 
+0

Danke, tut mir leid, dass ich anfangs keinen Code eingegeben habe. – AJH

+3

@AJH * "anfänglich" *? Soweit ich sehen kann, hast du noch nicht ... – Lankymart

0

Eine Powershell-Lösung mit zwei RegExes. Die erste teilt die Datei in Stücke, beginnend mit Computer Name

Die zweite verwendet eine benannte Erfassungsgruppe, um den Computernamen zu grep und überprüft den Zustand.

$InFile = ".\41145072.txt" 

$Delimiter = 'Computer Name:' 
$Escaped = [regex]::Escape($Delimiter) 
$Split  = "(?!^)(?=$Escaped)" 
$Search = [RegEx]'(?smi)Computer Name:\s+(?<ComputerName>[0-9a-z_-]+).*Fully Encrypted\r\nProtection Status:\s+Protection Off' 

(Get-Content $InFile -Raw) -split $Split | ForEach-Object { 
    If ($_ -match $Search){ 
     $matches.ComputerName 
    } 
} 
+1

Wo wird Powershell erwähnt ?, es ist bereits VBScript markiert und Batch-Datei benötigt keine dritte. – Lankymart

+0

@Lankymart Haben Sie heute schlechte Laune? Nun, der erste Satz erwähnt Powershell als Ursprung der Datei. Natürlich wäre es besser, zuerst die Pipe in ein anderes Powershell-Skript/Cmdlet zu platzieren, um die Filterung durchzuführen. Ich fühle mein Skript nicht außer Betrieb. Übrigens warst du es nicht, der mir zu Unrecht vorgeworfen hat, keine Lösung zu bieten? – LotPings

+0

Überhaupt nicht krank von Leuten, die die Richtlinien ignorieren/sie ignorieren, wenn es ihnen passt. Ihre Antwort ist in Ordnung, das Problem liegt in der Frage, also sollte durch den Eliminierungsprozess die Antwort nicht existieren, aber sie tut es. Ich habe dich zu Unrecht beschuldigt, du hast eine Quelle dafür? ... Ich erinnere mich ehrlich gesagt nicht. – Lankymart

0
@ECHO Off 
SETLOCAL 
SET "namefound=" 
SET "convstatfullenc=" 
SET "protstatoff=" 

SET "sourcedir=U:\sourcedir" 
SET "filename1=%sourcedir%\q41141572.txt" 
FOR /f "usebackqtokens=1,2*delims=: " %%a IN ("%filename1%") DO (
SET "lineprocessed=" 
IF /i "%%a"=="computer" IF /i "%%b"=="name" (
    SET "namefound=%%c" 
    SET "convstatfullenc=" 
    SET "protstatoff=" 
    SET "lineprocessed=Y" 
) 
IF /i "%%a"=="protection" (
    SET "protstatoff=" 
    IF /i "%%b"=="status" IF /i "%%c"=="protection off" (
    SET "protstatoff=Y" 
    SET "lineprocessed=Y" 
) 
) 
IF /i "%%a"=="conversion" (
    SET "convstatfullenc=" 
    SET "protstatoff=" 
    IF /i "%%b"=="status" IF /i "%%c"=="fully encrypted" (
    SET "convstatfullenc=Y" 
    SET "lineprocessed=Y" 
) 
) 
IF DEFINED lineprocessed IF DEFINED namefound IF DEFINED convstatfullenc IF DEFINED protstatoff (
    CALL ECHO %%namefound%% 
    SET "lineprocessed=" 
) 
IF NOT DEFINED lineprocessed (
    SET "convstatfullenc=" 
    SET "protstatoff=" 
) 
) 

GOTO :EOF 

Sie müssten die Einstellung von sourcedir zu ändern, um Ihre Umstände anzupassen.

Ich habe eine Datei mit dem Namen q41141572.txt verwendet, die Ihre Daten für meine Tests enthält.

auf dem ersten Wort arbeitet nur, wenn die Worte sind computer und name dann ein neues namefound zugeordnet ist und die beiden Fahnen convstatfullenc und protstatoff werden gelöscht und die Linie markiert lesen. Folglich werden die Steuerflags gelöscht, wenn ein neuer computer name auftritt.

Wenn conversion angetroffen wird, dann wird die Steuer Flags gelöscht und convstatfullenc wird nur dann gesetzt, wenn die Leitung status und fully encrypted enthält, wenn die Leitung als verarbeitet markiert.

wenn protection angetroffen wird, dann wird protstatoff nur eingestellt werden, wenn die Zeile enthält auch status und protection off, wenn die Leitung wieder verarbeitet markiert werden.

Wenn die Zeile verarbeitet wurde und jedes Flag gesetzt ist, ist jede Bedingung erfüllt, so dass der gespeicherte Name angezeigt wird. Das Löschen lineprocessed stellt sicher, dass die zwei Steuerungsflags im nächsten Schritt gelöscht werden.

Wenn also eine Zeile gefunden wird, die keine der drei Ziellinien ist, wird die Zeile nicht als verarbeitet festgelegt, daher werden die beiden Steuerungsflags gelöscht.

Wenn die conversion Linie gefunden wird, wird protstatoff gelöscht und convstatfullenckann eingestellt werden.

Wenn die protection Zeile gefunden wird, protstatoffkann eingestellt werden.

Der einzige Weg, in der beid Steuern Flags gesetzt werden kann, ist für die protection Linie und sowohl direkt nach der conversion Linie, um den vollständigen Test zu bestehen.

+0

Sie denken ehrlich, dass eine Frage ohne klares Problem, keine [mcve] und Zweideutigkeit dessen, was sie tatsächlich verwenden * (ich sehe, dass Sie sich für Batch-Datei entschieden haben) * sollte ermutigt werden, indem Sie sie beantworten? – Lankymart

+3

@Lankymart: Nein. Und Ja. Nach 15 Jahren Arbeitslosigkeit brauche ich etwas, um meine Gedanken aktiv zu halten. Es gibt nicht genug Probleme, um darauf zu bestehen, dass "die Regeln" eingehalten werden, also antworte ich, was mich amüsiert. Sicher - wenn jemand möchte, dass ich die Arbeit mache, die er nicht kann, dann werden sie entweder etwas lernen, so dass meine Bemühungen nicht verschwendet werden, oder sie werden gedankenlos Papageien, was ich gepostet habe, ohne es zu verstehen. Wenn das irgendwann in der Zukunft ein Problem für ihren Arbeitgeber verursacht, dann ist es für meine Zwecke geeignet, da die Wahl der Angestellten durch den Arbeitgeber dazu führt, sie zu beißen. Ich sehe es als kleinen Machiavellianer. – Magoo

+0

Sie können sich amüsieren, indem Sie Fragen stellen, abstimmen, bearbeiten und überprüfen ... Sie müssen nicht zum ohnehin schon großen Problem beitragen. – Lankymart

Verwandte Themen