远程注册表查询问题

时间:2016-12-19 07:00:16

标签: batch-file variables for-loop registry

批量使用此脚本通过注册表检查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的第二行)。谢谢:))

1 个答案:

答案 0 :(得分:2)

如果thingy在没有for循环的情况下工作且变量在for循环中设置为而不是,请考虑搜索Batch variable not set in for-loop boom 之类的内容会有很多像你这样的问题。
答案对所有人来说都是一样的:

使用Delayed Expansion

要使用它,请将行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?)。如果您已找到所需内容,请将示例中的字符串更改为您的需要 从systeminfoecho !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!所以你有两种处理方法:

  1. 只需删除错误类型处理
  2. 即可
  3. 删除部分&& echo positive result || echo negative result,以便根据命令的结果设置errorlevel,因为它已在检查XP时完成
  4. 您可以使用问题中的查询在命令行中自行测试:

    && 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%