viewfinder
Goto Top

CMD-Batch, Stringzerlegung, String in Token teilen und letztes Token bei unbekannter Anzahl von Token finden

Guten Morgen allseits,
ich hänge irgendwie fest und wäre für ein paar Ideen dankbar. Sorry vorweg. Es wird vermutlich keine Live-Diskusion. Ich sitze hier auf einer EDGE-Leitung in UTC+7. Gut das ich kein Administrator bin.
Meine Frage basiert auf der extrem komfortablen Ausgabe von "icacls.exe". Ich möchte den Inhalt der Ausgabe nach logischen Token trennen. Die Verarbeitung des Strings ist mir im Original nicht eindeutig genug.

back-to-topZiel

Zerlegung der Ausgabe "icacls "Objekt"" in Tokens mit logisch zusammen hängendem Inhalt. Das letzte Token bildet die Rechte zum Objekt ab und wird in Folge "[GroupLast]" genannt. Es soll leicht erkennbar und moeglichst performant getrennt werden. Grundlage ist die Ausgabe von "icacls.exe". Loesung muss auf CMD.exe basieren.

back-to-topStringbeispiele
F:\testbasis\script-local\exembles USER:[Group1][Group2][Group3][Group4][GroupLast]
USER:[GroupLast]

back-to-topLogisch abgeschlossene Komponenten
1. USER: existiert immer (als Voraussetzung)
2. [Group1]; kann existieren
3. [Group2] ... [Group*]; kann existieren
4. [GroupLast]; existiert immer (als Voraussetzung)

back-to-topAnmerkung
- Ueberfluessiges MS-Gelaber wird gefiltert
- Die Pfadausgabe wird eleminiert durch Variablenmanipulation
- Variablenersetzung mit "][" fuehrt nicht zum Ziel
- Ausgabe von *:*"[GroupLast]" erfolgt immer und an letzter Stelle
- Anzahl von [Group*] variiert
- Inhalt von [Group*] ist variabel
- Inhalt von [GroupLast] ist variabel
- "tokens=*" liefert Reststring (Rest nach Leerzeichenorgie)
- "delims=:" liefert originale Tokens
- "[GroupLast]" soll separiert werden
Es geht ausschliesslich um das Separieren von "[GroupLast]" zur Weiterverarbeitung.
Die Rechte sollen von der Rechteverteilung getrennt werden.

back-to-topLoesungsansatz

@echo off
setlocal
pushd %~dp0
setlocal enabledelayedexpansion

set "object=F:\Public\Projects\WWW\testbasis\script-local\exembles"  

FOR /F "tokens=* useback" %%B in (`icacls "%object%"^|findstr /R /C:":(.*.)"`) DO (  
	set B=%%B
	set B=!B:%object% =!
	set B=!B:^(=[!
	set B=!B:^)=]!
	echo Ausgabe: !B!
	echo          Gruetze ist jetzt Pudding mit Nuessen und Rosinen.
	echo Wunsch:  Nuesse links und Rosinen rechts raus.
	For /F "tokens=1-2 delims=:" %%C in ('echo !B!') DO (  
		echo Pudding            %%C
		echo                    Nuesse und Rosinen %%D
		echo                    WIE weiter oder anderst^?
		))

setlocal disabledelayedexpansion
popd
endlocal
goto :eof

Hoffentlich habe ich alle Prämissen genannt und es kostet nicht zu viele Nerven.
mfg Viewfinder

Content-Key: 195899

Url: https://administrator.de/contentid/195899

Printed on: April 23, 2024 at 23:04 o'clock

Member: Viewfinder
Viewfinder Dec 15, 2012 at 08:36:02 (UTC)
Goto Top
Geübt in Selbsunterhaltung mal der erste Ansatz. Ich hoffe das diejenigen, welche jetzt im Schlaf der Gerechten von Geschenkverpackung träumen, bei Erwachen mit frischen Elan doch noch über eine Lösung mittels Token nachdenken.

back-to-topErste unbefriedigende Lösung
- verhafte Nüsse und Rosinen in Variable
- verschenke Nüsse, behalte Rosinen

Eine Lösung über Tokens wäre etwas algemein gültiger, leichter lesbar und vermutlich performanter. Sie ist dann auch auf andere Beispiele einsetzbar.
Lebkuchen für alle, sogar mit Zuckerguß.

@echo off
setlocal
pushd %~dp0
setlocal enabledelayedexpansion

set "object=F:\Public\Projects\WWW\testbasis\script-local\exembles"  

for /F "tokens=* useback" %%B in (`icacls "%object%"^|findstr /R /C:":(.*.)"`) do (  
	set B=%%B
	set B=!B:%object% =!
	set B=!B:^(=[!
	set B=!B:^)=]!
	echo Ausgabe: !B!
	echo          Gruetze ist jetzt Pudding mit Nuessen und Rosinen.
	echo          Nuesse links und Rosinen rechts raus.
	For /F "tokens=1-2 delims=:" %%C in ('echo !B!') do (  
		echo Pudding            %%C
		echo                    Nuesse und Rosinen %%D
		echo                    WIE weiter oder anderst^?
		echo.
		echo Klaeglicher Versuch:
		echo --------------------
		set "RightsObject=%%D"  
		set "RightsObject=!RightsObject:[OI]=!"  
		set "RightsObject=!RightsObject:[CI]=!"  
		set "RightsObject=!RightsObject:[IO]=!"  
		set "RightsObject=!RightsObject:[NP]=!"  
		set "RightsObject=!RightsObject:[I]=!"  
		echo Nicht wirklich Updatefest und irgendwie unbefriedigend,
		echo Praesente Rechte zum Objekt sind: !RightsObject!
		))

setlocal disabledelayedexpansion
popd
endlocal
goto :eof
Member: bastla
bastla Dec 15, 2012 updated at 12:10:56 (UTC)
Goto Top
Hallo Viewfinder!

Soferne ich das richtig intrepretiere, soll doch aus der von "icacls" erzeugten User-/Gruppenliste - Beispiel am Prompt:
C:\Users\Admin>icacls C:\Windows
C:\Windows NT SERVICE\TrustedInstaller:(F)
           NT SERVICE\TrustedInstaller:(CI)(IO)(F)
           NT-AUTORITÄT\SYSTEM:(M)
           NT-AUTORITÄT\SYSTEM:(OI)(CI)(IO)(F)
           VORDEFINIERT\Administratoren:(M)
           VORDEFINIERT\Administratoren:(OI)(CI)(IO)(F)
           VORDEFINIERT\Benutzer:(RX)
           VORDEFINIERT\Benutzer:(OI)(CI)(IO)(GR,GE)
           ERSTELLER-BESITZER:(OI)(CI)(IO)(F)

1 Dateien erfolgreich verarbeitet, bei 0 Dateien ist ein Verarbeitungsfehler auf
getreten.

C:\Users\Admin>
der User/die Gruppe aus der letzten Zeile ermittelt werden:
for /F "delims=: " %%B in ('icacls "%object%"^|findstr /R /C:":(.*.)"') do set "GroupLast=%%B"
Wenn ich wirklich aus dem String
F:\testbasis\script-local\exembles USER:[Group1][Group2][Group3][Group4][GroupLast]
nur "GroupLast" erhalten wollte, würde ich das so versuchen (unter der Voraussetzung, dass "GroupLast" keine Leerzeichen enthält):
set "Zeile=F:\testbasis\script-local\exembles USER:[Group1][Group2][Group3][Group4][GroupLast]"  
set "Zeile=%Zeile:USER:=%"  
for %%i in (%Zeile:[= %) do for /f "delims=]" %%B in ("%i") do set "GroupLast=%%B"  
Grüße
bastla
Member: Viewfinder
Viewfinder Dec 16, 2012 at 02:28:53 (UTC)
Goto Top
Hallo bastla,
danke das Du Dir Zeit genommen hast und fuer den Gedanken Deiner Forschleife. Variablenersetzung im Befehlssatz ist mir neu. Wie ich an Deiner Antwort sehen kann, habe ich einen Fehler in der Beschreibung gemacht. Zu viele "!" eben. Eventuell gibt es auch keine Lösung. Ich versuche mich mal in einer kürzeren und präziseren Weise.
- Schwerpunkt "letzte Gruppe von Inhalten als Token"
- Diese Inhalte bilden die Rechte ab
- Als Beispiel und aktuelles Problem dient die "Ausgabe icacls"

Schauen wir uns die Ausgabe an. Man kann nicht behaupten, das es ein Produkt einer Weihnachtsfeier ist. Und wo wir schon dabei sind, bietet NT-AUTORITÄT\SYSTEM: gleich den nächsten Anlass zur Freude.
So nun im zweiten Anlauf konkret und nicht allgemein. Der nicht benötigten Müll ist bereits entsorgt.

Was bleibt, ist Folgendes:
USER:[I][OI][CI][NP][IO][DENY][lange,Liste,mit,Permissions]

Das "DENY" ist mir bei der Marketing gerechten Ausgabe durchgeruscht. Sorry! Die gewünschte Lösung wäre jetzt etwas in der folgenden Art.
USER:[I]:[OI][CI][NP][IO]:[DENY][lange,Liste,mit,Permissions]
Token 1 - Username, Handling kein Problem da Delimiter existiert
Token 2 - keine eigenen Rechte, Handling kein Problem ist eindeutig
Token 3 - Vererbungslogig, Handling aufwendig aber kein Problem da für die Kombinationen eigene Filter notwendig sind
Token 4 - Auflistung der Rechte, letztes Token

Problemstellung
Ea kann sein, das ich eine Schneise schlagen will, wo es keinen Wald gibt. Die bisher gefundenen Lösungen basieren auf dem Löschen der Inhalte von Token 1-3. Diese Token sind einduetig, solange wie der Username nicht mit einer Pfadangabe identisch ist oder aus einer Datei ausgelesen (Problematik Umlaute-Sonderzeichen) werden muss.
Es bleibt das letzte Token. Das "DENY" beschreibt das eigentliche Problem. Mit nur einer Standalone-Maschine kann ich nicht jeden Problemfall rekonstruieren. Die Trennung in logische Token, sollte mich von diesem Problem befreien.

Doch mit der von den Rechten gesonderten Ausgabe des "DENY" hat sich die Sache für icacls erledigt. Delinquent hat zu früh geschrien. Es sind jetzt zwei letzte Token.

Ich werde jetzt mal mit Deinem Vorschlag in dieser Richtung weiter basteln und sehen was übersichtlicher und oder performanter ist.
for %%i in (!VAR:[= !) do for /f "delims=]" %%B in ("%%i") do set "GroupLast=%%B"  
Eventuell läßt sich die Ersetzung mit einem Rutsch erledigen. Morgen ist Holiday und danach sollte die Lösung fertig sein. Dann gibs hier die Auflösung und einen Gelöst-Haken.

mfg
Viewfinder
Member: Viewfinder
Viewfinder Dec 16, 2012 updated at 06:04:45 (UTC)
Goto Top
fertisch
Der Rohentwurf steht und morgen ist frei.

@bastla
Danke für die Hilfe. Es hat mir viel suchen erspart.
Die Lösung der Variablenersetzung in "For" ist komfortabler und übersichtlicher. Performance-Einbußen konnte ich im Hunderstel-Sekunden-Bereich nicht ermitteln. Doch wenn ich der Schleife auch nur ein echo mit der neuen Variable hinzufüge, bricht die Geschichte um 30% ein.


So noch schnell die Gesamtlösung und dann Mittach:
:ENVIRONMENT
@echo off
setlocal
pushd %~dp0
setlocal enabledelayedexpansion

	
:ROUTINE
call :INHERITANCE_NODES

	
:EXIT
setlocal disabledelayedexpansion
popd
endlocal
goto :eof


:INHERITANCE_NODES
setlocal
cls
echo.
echo   ===================================================================
echo   =              Find Inheritance Parent directory                  =
echo   ===================================================================
echo.
echo   Dieses Tool dient der Analyse von vergebenen Berechtigungen unter
echo   EINEM Erbknoten. Der naechst hoehere Erbknoten wird ermittelt und
echo   seine Struktur ab dem Verzeichnis der Abfrage ausgewiesen. Voraus-
echo   setzung ist eine entsprechende Berechtigung.
echo.
echo   Einsatz:
echo   Ermittlung des Verzeichnisses, welches als "Parent Directory" im  
echo   Sinn von "icacls /save" verstanden werden kann. Dieses Tool ist  
echo   Bestandteil eines etwas komplexeren Projektes.
echo.
echo   Begriffe:
echo   Eine Protokollierung ist noch nicht eingearbeitet. Doch die
echo   vorliegende Ausgabe beinhaltet bereits wesentliche Informationen.
echo   Zuornungen beziehen sich auf das Berechtigungsystem.
echo   Benutzer:         Weist den User zur jeweiligen Berechtigung aus
echo   Quelle Vererbung: Verzeichnis dem die jeweiligen Berechtigungen
echo                     zugeordnet sind
echo   Permission:       Gruppierung von Berechtigungen
echo   Object:           Das betrachtete Objekt selbst. Hier immer Verzeichnis
echo   Directories:      Alle dem "Object" untergeordneten Verzeichnisse  
echo   Files:            Alle dem "Object" untergeordneten Dateien  
echo   Sub Directories:  Dem "Object" direkt untergeordnete Verzeichnisse  
echo   Sub Files:        Dem "Object" direkt untergeordnete Dateien  
echo   ---------------------------------------------------------------------
echo   Bitte Verzeichnis zu dem der Erbknoten ermittelt werden soll eingeben
echo.
set /p "FilePath="  
set "ParentDir=%FilePath%"  
echo   Pruefverzeichnis: %FilePath%
echo.
	:FindParent
set "Parent=0"  
FOR /F "tokens=* useback" %%A in (`icacls "%ParentDir%"^|findstr /R /C:":(.*.)"`) DO (  
	set A=%%A
	set A=!A:%ParentDir% =!
	set A=!A:^(=[!
	set A=!A:^)=]!
	For /f "tokens=2 delims=:" %%1 in ('echo !A!^|findstr /L /C:"[I]["') DO (  
		set "Parent=1"  
		)
	set "Objects="  
	IF "!Parent!" EQU "0" (  
		For /F "tokens=1-2 delims=:" %%B in ('echo !A!') do (  
			for /f %%1 in ('echo %%C^|findstr /V /L /C:"[IO]["') do (  
				set "Objects=Object;"  
				)
			for /f %%2 in ('echo %%C^|findstr /L /C:"[CI]["') do (  
				for /f %%a in ('echo %%C^|findstr /L /C:"[NP]["') do (  
					set "Objects=!Objects!Sub Directories;"  
					)
				for /f %%a in ('echo %%C^|findstr /V /L /C:"[NP]["') do (  
					set "Objects=!Objects!Directories;"  
					)
				)
			for /f %%3 in ('echo %%C^|findstr /L /C:"[OI]["') do (  
				for /f %%a in ('echo %%C^|findstr /L /C:"[NP]["') do (  
					set "Objects=!Objects!Sub Files;"  
					)
				for /f %%a in ('echo %%C^|findstr /V /L /C:"[NP]["') do (  
					set "Objects=!Objects!Files;"  
					)
				)
			set "Permissions=%%C"  
			for %%4 in ([OI] [CI] [IO] [NP] [I]) do set "Permissions=!Permissions:%%4=!"  
			echo   Benutzer:         %%B
			echo   Quelle Vererbung: %ParentDir%
			echo   Permission:       !Permissions!
			echo                     Recht gilt fuer: !Objects!
			echo.
			)
		)
	)
if "%Parent%" EQU "1" (  
	for /F "tokens=* useback" %%I in (`echo %ParentDir%`) do (  
		set "ParentDir=%%~dpI"  
		set "ParentDir=!ParentDir:~0,-1!"   
		)
	goto :FindParent
	)
echo   Erbknoten:     %ParentDir%
endlocal
goto :eof

Dank an alle die sich bemüht haben
Member: pieh-ejdsch
pieh-ejdsch Dec 16, 2012, updated at Dec 21, 2012 at 09:28:24 (UTC)
Goto Top
moin Viewfinder,

den ElternOrnder bekommst Du leichter so:
for %%i in ("%ParentDir%\..") do if "%%~fi" neq "%ParentDir%" (set "ParentDir=%%~fi" &goto :FindParent) else goto :EndeimGelaende  

Gruß Phil
Member: Viewfinder
Viewfinder Dec 18, 2012 at 05:39:42 (UTC)
Goto Top
@pieh-ejdsch
Danke Phil, leider funktionieren meine Computer nicht so gut wie das Forum hier. Die "CD.."- Variante ist bei mir weder unter Windows7 noch unter XP3 anwendbar. Die Variable kommt als Text zurück. Egal in welcher For- Variante. Ich schau mich mal um, ob es hier schon etwas in Richtung Wunderwelt CMD gibt. Wenn nicht mache ich zu diesem Thema einen Beitrag auf. Ewventuell läßt sich das Problem ja klären.

mfg
Viewfinder