批量使用此脚本通过注册表检查XP。
@echo off
pushd %~dp0
for /f "usebackq tokens=*" %%A in ("%~dp0pxhosts.txt") do (
reg query "\\%%A\HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" | find /i "5.1" > NUL && set OS=XP || set OS=NEWER
echo %os%
pause
)
在pxhost中的我有pc的列表来检查xp然后做某事或不做。 但是,我不能让上述工作。永远不会设置该变量,它只是回显“windows_NT”。但是,如果我将for循环输出并运行不带变量的reg查询: -
reg query "\\xp-4c54fa50d0da\HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" | find /i "5.1" > NUL && set OS=XP || set OS=NEWER
如果我将“5.1”更改为“5.7”以进行测试,则回声工作并报告“XP”或“更新”。
发生了什么事?谢谢。
感谢您的回答,但现在我遇到了更多问题
从这里,我现在可以回应正确的回复,但是这个呼叫根本不起作用。我有一个XP,赢得7 32并在文本文件pxhosts中测试10 64。 XP是列表中的第一个,即使正确回显,它也会被忽略。有些东西阻止了呼唤的发生。真的让我心理这个哈哈。
我正在尝试编写一个适用于XP filr系统或32或64(更新的窗口)的远程权限脚本。总代码如下: -
@echo off
setlocal enabledelayedexpansion
for /f "usebackq tokens=*" %%A in ("%~dp0pxhosts.txt") do (
reg query "\\%%A\HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" | find /i "5.1" > NUL && set pctype=XP || set pctype=NEWER
cls
echo !pctype!
pause
if !pctype! == !XP! ( call :XP !%%A!)
reg query "\\%%A\HKLM\Hardware\Description\System\CentralProcessor\0" | find /i "x86" > NUL && set arc=32 || set arc=64
cls
echo !arc!
pause
if !arc! == !64! ( call :64 !%%A!)
if !arc! == !32! ( call :32 !%%A!)
)
:32
echo 32 okay
pause
icacls "\\%1\C$\ProgramData\folderFoo" /T /C /grant(:r) "Domain Users":(OI)(CI)(F) /inheritance:e >> "%~dp0%1.txt" 2>&1
pause
rem return from a subroutine
exit /B
:64
echo 64 okay
pause
icacls "\\%1\C$\Program Files (x86)\Folderfoo" /T /C /grant(:r) "Domain Users":(OI)(CI)(F) /inheritance:e >> "%~dp0%1.txt" 2>&1
pause
rem return from a subroutine
exit /B
:XP
echo xp okay
pause
CACLS "\\%1\C$\Documents and Settings\All Users\Application Data\Folderfoo" /E /T /C /G "Domain Users":F >> "%~dp0%1.txt" 2>&1
pause
rem return from a subroutine
exit /B
new edit 201216
for /f "usebackq tokens=*" %%A in ("%~dp0pxhosts.txt") do (
reg query "\\%%A\HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" | find /i "5.1" > NUL
IF %ERRORLEVEL%==0 set pctype=XP
IF %ERRORLEVEL%==1 set pctype=NO
reg query "\\%%A\HKLM\Hardware\Description\System\CentralProcessor\0" | find /i "x86" > NUL
IF %ERRORLEVEL%==0 set arc=32
IF %ERRORLEVEL%==1 set arc=64
IF !pctype!==XP (call :xp %%A)
IF !pctype!==NO IF !arc!==32 (call :32 %%A)
IF !arc!==64 (call :64 %%A)
)
现在使用reg查询获取64或32,但是因为XP机器将始终是32位机器,所以它仍然为32位的新Windows PC运行代码。我的XP子程序正在处理docuemnts和settings文件夹,较新的32台机器只是用户文件夹格式。
我需要在XP机器,32位新机器和64位机器上运行子程序。目前xp代码在32位机器上运行,反之亦然,因为它们共享32位架构。
我已经尝试过通过仅运行32位例程来消除问题,如果pc是更新的,具有32位文件结构的变量(IF的第二行)。谢谢:))
答案 0 :(得分:2)
如果thingy在没有for循环的情况下工作且变量在for循环中设置为而不是,请考虑搜索Batch variable not set in for-loop
和 boom 之类的内容会有很多像你这样的问题。
答案对所有人来说都是一样的:
要使用它,请将行setlocal EnableDelayedExpansion
添加到批处理文件的开头,并且需要在一组封闭的括号中使用变量,例如for-loop或if-condition change {{1} } %myVar%
。
验证示例:
!myVar!
推理:
在批量关闭时,在达到开始时计算括号组。在上面的示例中,这意味着当程序到达@echo off
setlocal EnableDelayedExpansion
set foo=foo
if 1==1 (
set foo=bar
echo Not delayed: %foo%
echo Delayed: !foo!
) ELSE (
echo If you land here something went heavily wrong...
)
时,它知道if 1==1
的值为“foo”,尽管我之前似乎已经改变了它。
另一种方法是使用
foo
在你的例子中,你甚至不需要那个变量......在你设置 call echo %%myVar%%
值的相同位置你也可以简单地回应它:
OS
- > ... && set OS=XP || set OS=NEWER
在访问循环中设置的变量时,您只需要感叹号!到目前为止,你发现了两个重大错误:
1)For循环变量在循环标题中设置,并且这是此规则的例外:... && echo XP || echo NEWER
是访问它的正确方式,而不是%%A
2)如果你想进行像!%%A!
之类的字符串比较,你不应该围绕字符串来检查感叹号:
if varValue == thisString
应该在这里做到这一点!
否则,比较看起来像if !arc!==64
,这不是我想要的行为。
再次阅读您的问题编辑:
有些事情正在阻止调用的发生
上面第2点中描述的问题确实存在问题:)
经过短暂的搜索并在结果中玩了一下后,我想出了这个(执行机器时需要Windows 7+;使用Windows 10 Pro进行测试):
if 64==!64!
说明:
从文件中读取计算机名称。从命令@echo off
setlocal EnableDelayedExpansion
for /f "usebackq tokens=*" %%A in ("%~dp0pxhosts.txt") do (
for /f "tokens=2 delims=:" %%B in ('systeminfo /s "%%~A" ^| findstr /i "Systemtype"') do (
call :removeLeadingSpaces "%%~B" type
echo !type!
)
for /f "tokens=2 delims=:" %%C in ('systeminfo /s "%%~A" ^| findstr /i "Operatingsystemname"') do (
call :removeLeadingSpaces "%%~C" osName
echo !osName!
)
)
pause
Goto:eof
:removeLeadingSpaces
for /f "tokens=* delims= " %%f in ("%~1") do set %2=%%f
的输出中获取第二部分,查询特定字符串“Systemtype”和“Operatingsystemname”。 systeminfo /s <computername>
可以逃脱管道符号^
。然后它将字符串发送到一个子函数,该子函数截断前导空格并将它们设置为指定的变量。
注意:用于查询的字符串可能因不同的语言设置而异!以上版本可以从我的德语OS中自由翻译!要检查它们的语言设置,请继续打开命令提示并键入|
然后按输入现在查找所需的命令。
Systemtype输出处理器体系结构,OSname输出操作系统的名称(谁会想到ey?)。如果您已找到所需内容,请将示例中的字符串更改为您的需要
从systeminfo
和echo !type!
所说的地方做这些变量。还有问题吗?随意问一下!
你的问题(我认为)就在这里:
echo !osName!
当使用直接使用reg query "\\%%A\HKLM\Hardware\Description\System\CentralProcessor\0" | find /i "x86" > NUL && set arc=32 || set arc=64
IF ERRORLEVEL==0 set arc=32
IF ERRORLEVEL==1 set arc=64
处理查找结果的方式时,errorlevel将始终驻留在0!所以你有两种处理方法:
&& echo positive result || echo negative result
,以便根据命令的结果设置errorlevel,因为它已在检查XP时完成您可以使用问题中的查询在命令行中自行测试:
&& set arc=32 || set arc=64
如果您没有XP计算机(我希望您这样做),这应该回显1)。这是因为reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" | find /i "5.1" > NUL
echo %ERRORLEVEL%
找不到指定的字符串 - &gt;虚假价值。
现在重置错误级别:
find
试试这个:
set ERRORLEVEL=0
是没有直接错误级别处理但是根据reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" | find /i "5.1" > NUL && echo should be 0 || echo should be 1
命令的直接结果进行操作的版本。
现在做find
你会注意到它是0,尽管上面的命令应该返回一个假值。
最后它是一个致命的空间太多......一个空间搞砸了部分剧本。
基本脚本:
echo %ERRORLEVEL%