管理者として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%
バッチファイルは setlocal または delayedexpansion を使用していないため、バッチファイルを呼び出している環境で%user%
が定義されている場合にのみ機能します。
バッチファイル内に設定されたsetlocal
変数がないため、呼び出し元のコマンドShellにリークされ、次にバッチファイルが呼び出されたときに使用できます。
バッチファイル内(最初に呼び出されたとき)%user%は、コードブロック(if
)内で参照されているため、バッチファイル内では使用できません。
バッチファイルが実行されると、コマンドプロセッサ(CMD.exe)は完全な行を解析し、 複合コマンド を完了します。 変数は、行のコマンドが実行される前に、一度だけ値に置き換えられます。
有効にした場合 delayedexpansion :
拡張の遅延により、バッチファイル内の変数が解析時ではなく実行時に拡張されます。このオプションはSETLOCALEnableDelayedExpansionコマンドでオンになります。
したがって、バッチファイルを初めて呼び出すときは%user%
は実行時に未定義であり、WMIC
コマンドは質問で指摘したエラーで失敗します。
2回目にバッチファイルを呼び出すと、%user%
が定義されます(前回の実行の値とバッチファイルが機能しているように見えます。
異なるユーザー名を2回入力すると、バッチファイルが間違ったSIDを返すことに注意してください(ユーザーを使用します)名前は最初に呼び出されたときに入力されました)。
次の変更を行う必要があります。
バッチファイルの先頭にsetlocal enabledelayedexpansion
を追加します。
%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