2016-06-20 6 views
0

Ich habe ein Batch-Skript, das alle Dienste auflistet, nimmt die BINARY_PATH, entfernt alle Zeilen, die c "\ Windows" enthalten und stellt eine Liste von BINARY_PATHS.FOR Schleife Leerzeichen und Behandlung

Die Idee besteht darin, diese Liste dann in ICACLS zu übergeben, um die Berechtigungen zu bestimmen, die auf jedem dieser ausführbaren Dateien festgelegt sind.

Das Problem, das ich habe, ist, dass einige BINARY_PATHS führende und nachfolgende enthalten. " Also musste ich dafür Rechnung tragen, indem ich die delims =" zu meiner for/f-Anweisung hinzufüge.

Im Folgenden finden Sie die Batchdatei, die

for /f "tokens=2" %%n in ('sc query state^= all ^| findstr SERVICE_NAME') do (
    for /f "delims=: tokens=1*" %%r in (
    'sc qc "%%~n" ^| findstr BINARY_PATH_NAME' 
) do (
    for /f tokens^=1-2^ delims^=^" %%x in ('echo %%~s^| findstr /V /I "c:\windows\system32"') do (
     echo "%%~x%%~y" 
     ) 
) 
) 

Der ECHO Ausgang ist wie folgt auf ECHO gibt - eine schöne, saubere Liste würde es von dem führenden Raum scheint auseinander

" C:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_state.exe" 
" C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorsvw.exe" 
" C:\Windows\Microsoft.Net\Framework\v3.0\WPF\PresentationFontCache.exe" 
" C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\infoc 
ard.exe" 
" C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\SMSvc 
Host.exe" 
" C:\Program Files\Photodex\ProShow Producer\ScsiAccess.exe" 
" C:\Windows\servicing\TrustedInstaller.exe" 
" C:\Program Files\VMware\VMware Tools\vmtoolsd.exe" 

Wenn ich versuche, die Ausgabe an Icacls ohne das führende und das nachfolgende "" zu übergeben, bricht es zusammen, weil in einigen PATHs Leerzeichen vorhanden sind.

ICACLS Batch-Datei:

for /f "tokens=2" %%n in ('sc query state^= all ^| findstr SERVICE_NAME') do (
    for /f "delims=: tokens=1*" %%r in (
    'sc qc "%%~n" ^| findstr BINARY_PATH_NAME' 
) do (
    for /f tokens^=1-2^ delims^=^" %%x in ('echo %%~s ^| findstr /V /I "c:\windows\system32"') do (
     icacls %%~x%%~y 
     ) 
) 
) 

Einige Ausgabe von ICACLS Partie:

C:\Windows\Microsoft.Net\Framework\v3.0\WPF\PresentationFontCache.exe NT SERVICE 
\TrustedInstaller:(F) 
                     BUILTIN\Ad 
ministrators:(RX) 
                     NT AUTHORI 
TY\SYSTEM:(RX) 
                     BUILTIN\Us 
ers:(RX) 

Successfully processed 1 files; Failed processing 0 files 
Invalid parameter "Communication" 
Invalid parameter "Communication" 
Invalid parameter "Files\Photodex\ProShow" 
C:\Windows\servicing\TrustedInstaller.exe NT SERVICE\TrustedInstaller:(F) 
              BUILTIN\Administrators:(RX) 
              NT AUTHORITY\SYSTEM:(RX) 
              BUILTIN\Users:(RX) 

Successfully processed 1 files; Failed processing 0 files 
Invalid parameter "Files\VMware\VMware" 

Irgendwelche Ideen?

+0

Die äußerste "for/f" -Schleife verwendet die Variable '%% n', die innerste verwendet implizit auch die Variable' %% n' wegen '%% m' und den' Tokens = 1-2 'Option; Obwohl es funktioniert, empfehle ich, nicht überlappende Variablen für die innerste Schleife zu verwenden (z. B. '%% x' und so auch' %% y'). Um führende und nachfolgende "" "zu entfernen, brauchen Sie nicht die Option" delims^=^"'; geben Sie einfach 'for/f" an delims = "%% x in ('echo %% ~ s') echo% % ~ x' (der '~' Modifikator entfernt die Anführungszeichen) ... – aschipfl

+0

danke gute Idee. – Ankh2054

+0

Das Problem ist mehr die führenden und nachgestellten Leerzeichen als die "". – Ankh2054

Antwort

1

Sie haben absolut Recht, Pfade zwischen Anführungszeichen zu setzen, um Probleme mit Leerzeichen zu vermeiden. Aber anstatt zu entfernen und führende und nachfolgende Leerzeichen, die auch in der "" enthalten sind, würde ich versuchen, sie nicht zu produzieren, anstatt sie später zu beseitigen.


Der führende Raum kommt aus der Mitte for /f Schleife:

for /f "delims=: tokens=1*" %%r in ('sc qc "%%~n" ^| findstr BINARY_PATH_NAME') do (...) 

Der gefilterte sc qc Befehl erzeugt eine Ausgabe Zeilen wie:

 BINARY_PATH_NAME : C:\Windows\System32\spoolsv.exe 
     BINARY_PATH_NAME : "C:\Program Files\iPod\bin\iPodService.exe" 

Mit Ihrer "delims=: tokens=1*" Option, die Teil nach dem Trennzeichen (:) hält einen führenden Platz. Um dies zu umgehen, fügen Sie den Speicherplatz als weiteres Trennzeichen hinzu, stellen Sie jedoch sicher, dass es das letzte Zeichen in der Optionszeichenfolge ist: "tokens=1* delims=: ".


das nachstehende Leerzeichen kommt von der verrohrt echo Befehlszeile durch die innere Schleife for /f geparst:

for /f tokens^=1-2^ delims^=^" %%x in ('echo %%~s ^| findstr /V /I "c:\windows\system32"') do (...) 

Der Raum zwischen echo %%~s^| und auch in dem Ausgang enthalten ist. Daher einfach entfernen. Es ist nicht erforderlich, die Optionszeichenfolge tokens^=1-2^ delims^=^" zu definieren, da die Schleife for /f keine Anführungszeichen zum Analysieren erhalten sollte (aufgrund des Modifikators ~ in %%~s), sodass "delims=" ausreicht. Verwenden Sie daher %%~x nur im Schleifenkörper.
Außerdem schlage ich vor, echo(%%~s anstelle von echo %%~s zu schreiben, um ECHO is on/off. Nachrichten zu vermeiden, wenn %%~s leer ist (obwohl das nie passieren sollte).


Ein weiteres Problem besteht darin, dass Service von sc query state= all abgerufenen Namen und weiß-Leerzeichen enthalten kann; zum Beispiel:

SERVICE_NAME: iPod Service 

So für die äußere for /f Schleife ist die "tokens=2" Option nicht optimal; Im obigen Beispiel würde nur iPod zurückgegeben werden. Korrigieren Sie es daher auf "tokens=1*" und ignorieren Sie das letzte Token.


Da Literalzeichenfolgen nur gesucht, ersetzte ich die findstr Instanzen von find, mit Ausnahme des letzten, weil find nur einen einzigen Suchbegriff unterstützt. Ich habe der restlichen findstr Instanz einen weiteren Suchstring hinzugefügt, um auch 64-Bit Windows Systeme abzudecken, wo auch ein Verzeichnis C:\Windows\SysWOW64 existiert, von dem ich annehme, dass Sie es auch herausfiltern wollen.


Hier ist der Fixcode:

@echo off 
for /f "tokens=1*" %%m in ('sc query state^= all ^| find "SERVICE_NAME"') do (
    for /f "tokens=1* delims=: " %%r in ('sc qc "%%~n" ^| find "BINARY_PATH_NAME"') do (
     for /f "delims=" %%x in ('echo(%%~s^| findstr /L /V /I /C:"%SystemRoot%\System32" /C:"%SystemRoot%\SysWOW64"') do (
      ECHO icacls "%%~x" 
     ) 
    ) 
) 

Entfernen Sie die Großbuchstaben ECHO nach erfolgreicher Prüfung, um die icacls Befehlszeilen auszuführen.

+0

danke. Tolle Erklärung :) – Ankh2054