web-dev-qa-db-ja.com

WMICエラー:バッチスクリプトを最初に実行した後、使用可能なインスタンスがありません

管理者としてcmd.exeを実行し、このスクリプトを実行します。最初に実行すると、常にInstances Availableが表示されます。実際にSIDを出力するには、2回目(場合によっては3〜4回)実行する必要があります。どうして?

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%
2
user745333

実際にSIDを印刷するには、2回目(場合によっては3〜4回)実行する必要があります。

バッチファイルは setlocal または delayedexpansion を使用していないため、バッチファイルを呼び出している環境で%user%が定義されている場合にのみ機能します。

バッチファイル内に設定されたsetlocal変数がないため、呼び出し元のコマンドShellにリークされ、次にバッチファイルが呼び出されたときに使用できます。

バッチファイル内(最初に呼び出されたとき)%user%は、コードブロック(if)内で参照されているため、バッチファイル内では使用できません。

バッチファイルが実行されると、コマンドプロセッサ(CMD.exe)は完全な行を解析し、 複合コマンド を完了します。 変数は、行のコマンドが実行される前に、一度だけ値に置き換えられます。

有効にした場合 delayedexpansion

拡張の遅延により、バッチファイル内の変数が解析時ではなく実行時に拡張されます。このオプションはSETLOCALEnableDelayedExpansionコマンドでオンになります。

したがって、バッチファイルを初めて呼び出すときは%user%は実行時に未定義であり、WMICコマンドは質問で指摘したエラーで失敗します。

2回目にバッチファイルを呼び出すと、%user%が定義されます(前回の実行の値とバッチファイルが機能しているように見えます

異なるユーザー名を2回入力すると、バッチファイルが間違った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

参考文献

0
DavidPostill