WMIC 错误:第一次执行批处理脚本后没有可用的实例

WMIC 错误:第一次执行批处理脚本后没有可用的实例

我以管理员身份运行 cmd.exe 并运行此脚本,第一次运行它时总是会出现此错误Instances Available,我必须第二次执行它(有时 3-4 次)才能真正打印 SID...为什么?

if %errorLevel% == 0 (
    SET Users="dir C:\Users\ /B"
    for /F "tokens=2,*" %%a in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" /v ProfileImagePath /s ^| find "REG_EXPAND_SZ" ^| findstr /v /i "\\windows\\ \\system32\\"') do (
        echo %%~nb
        echo.
    )
    echo.

    SET /p "util=Type the username"

    for /f "delims= " %%a in ('"wmic path win32_useraccount where name='%util%' get sid"') do (
        if not "%%a"=="SID" (          
            set _sid=%%a
            goto :loop_end
        )
    )
) else (
    for /f "delims= " %%a in ('"wmic path win32_useraccount where name='%USERNAME%' get sid"') do (
        if not "%%a"=="SID" (          
            set _sid=%%a
            goto :loop_end
        )
    )
)

:loop_end
echo %%_sid%%=%_sid%

答案1

我必须执行第二次(有时 3-4 次)才能真正打印 SID

您的批处理文件未使用设置本地或者延缓扩张%user%因此,仅当在调用批处理文件的环境中定义时,它才会起作用。

由于setlocal批处理文件内部设置的变量不足,因此泄漏到调用命令 shell 中,然后在下次调用批处理文件时可以使用它们。

在批处理文件中(第一次调用时),%user%在批处理文件中不可用,因为它在代码块中被引用(if):

执行批处理文件时,命令处理器(CMD.exe)将解析完整的行并完成复合命令在执行行命令之前,变量仅被其值替换一次。

如果您启用延缓扩张

扩张延迟将导致批处理文件中的变量在执行时而不是解析时展开,此选项通过 SETLOCAL EnableDelayedExpansion 命令打开。

因此,第一次调用批处理文件%user%在执行时未定义,并且WMIC命令失败并出现您在问题中指出的错误。

第二次调用批处理文件时%user%会定义(使用上次执行的值和批处理文件出现上班。

请注意,如果您输入不同的批处理文件第二次将返回用户名错误的 SID(它将使用第一次调用时输入的用户名)。

您需要进行以下更改:

  1. setlocal enabledelayedexpansion在批处理文件的开头添加。

  2. %util%用。。。来代替!util!

修改后的批处理文件:

@echo off
setlocal enabledelayedexpansion
if %errorLevel% == 0 (
  SET Users="dir C:\Users\ /B"
  for /F "tokens=2,*" %%a in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" /v ProfileImagePath /s ^| find "REG_EXPAND_SZ" ^| findstr /v /i "\\windows\\ \\system32\\"') do (
        echo %%~nb
    echo.
    )
  echo.

  SET /p "util=Type the username"
  echo !util!
  for /f "delims= " %%a in ('"wmic path win32_useraccount where name='!util!' get sid"') do (
    if not "%%a"=="SID" (          
      set _sid=%%a
      goto :loop_end
    )
  )
) else (
  for /f "delims= " %%a in ('"wmic path win32_useraccount where name='%USERNAME%' get sid"') do (
    if not "%%a"=="SID" (          
      set _sid=%%a
      goto :loop_end
    )
  )
)

:loop_end
echo %%_sid%%=%_sid%
endlocal

用法示例:

> test
DavidPostill

ntp

Administrator


Type the usernameDavidPostill
DavidPostill
%_sid%=S-1-5-21-1699878757-1063190524-3119395976-1000

进一步阅读

相关内容