我有一个列出所有服务的批处理脚本,接受BINARY_PATH,删除包含c“\ windows”的所有行,并提供BINARY_PATHS列表。
我们的想法是将该列表传递给ICACLS,以确定在每个可执行文件上设置的权限。
我遇到的问题是某些BINARY_PATHS包含前导和尾随“。 因此,我必须通过将delims =“添加到my for / f语句来解释这一点。
以下是输出到ECHO的批处理文件
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"
)
)
)
ECHO输出如下 - 一个漂亮的清洁列表,它与领先的空间区别开来
" 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"
当我尝试将输出传递给没有前导和尾随的icacls时,它会崩溃,因为某些路径中有空格。
ICACLS批处理文件:
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
)
)
)
ICACLS批次的一些输出:
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"
有什么想法吗?
答案 0 :(得分:1)
将引号放在引号之间是绝对正确的,以避免出现白色空格问题。
但是,我不会删除和引导和尾随""
中包含的空格,而是试图不生成它们而不是在以后消除它们。
前导空格来自中间for /f
循环:
for /f "delims=: tokens=1*" %%r in ('sc qc "%%~n" ^| findstr BINARY_PATH_NAME') do ( ... )
过滤的sc qc
命令生成输出行,如:
BINARY_PATH_NAME : C:\Windows\System32\spoolsv.exe BINARY_PATH_NAME : "C:\Program Files\iPod\bin\iPodService.exe"
使用"delims=: tokens=1*"
选项,分隔符(:
)后面的部分保留一个前导空格。
要解决此问题,请将空格添加为另一个分隔符,但请确保它是选项字符串中的最后一个字符:"tokens=1* delims=: "
。
尾随空格来自内部echo
循环解析的管道for /f
命令行:
for /f tokens^=1-2^ delims^=^" %%x in ('echo %%~s ^| findstr /V /I "c:\windows\system32"') do ( ... )
echo %%~s
和^|
之间的空格也包含在输出中。因此,只需删除它。
没有必要定义选项字符串tokens^=1-2^ delims^=^"
,因为for /f
循环不应该接收任何引号来解析(由于~
中的%%~s
修饰符),所以"delims="
就足够了。因此,仅在循环体中使用%%~x
此外,我建议写echo(%%~s
而不是echo %%~s
,以便在ECHO is on/off.
为空时避免%%~s
条消息(尽管这绝不会发生)。
另一个问题是sc query state= all
检索的服务名称也可能包含空格;例如:
SERVICE_NAME: iPod Service
因此,对于外部for /f
循环,"tokens=2"
选项不是最佳选项;在上面的示例中,仅返回iPod
。因此,将其更正为"tokens=1*"
并忽略forst令牌。
由于只搜索文字字符串,我将findstr
实例替换为find
除了最后一个,因为find
仅支持单个搜索字符串。
我在剩余的findstr
实例中添加了另一个搜索字符串,以便覆盖目录C:\Windows\SysWOW64
也存在的64位Windows系统,我假设您也要过滤掉。
这是固定代码:
@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"
)
)
)
成功测试后删除大写ECHO
以执行icacls
命令行。