WMIC Error: No Instances Available after first execution of my batch script

2

I run cmd.exe as administrator and run this script, the first time I run it I always get Instances Available, I have to execute it a second time (sometimes 3-4 times) to actually print the SID... why?

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%

user745333

Posted 2017-07-04T15:59:29.570

Reputation: 23

Answers

0

I have to execute it a second time (sometimes 3-4 times) to actually print the SID

Your batch file is not using setlocal or delayedexpansion so it will only work if %user% is defined in the environment that is calling the batch file.

Because of the lack of setlocal variables set inside the batch file are leaked into the calling command shell and they are then usable the next time the batch file is called.

Inside the batch file (the first time it is called) %user% is not usable inside the batch file because it is referenced inside a code block (if):

When a batch file is executed, the command processor (CMD.exe) will parse complete lines and complete compound commands. Variables are replaced by their values just once, BEFORE the commands of the line are executed.

If you enable delayedexpansion:

Delayed Expansion will cause variables within a batch file to be expanded at execution time rather than at parse time, this option is turned on with the SETLOCAL EnableDelayedExpansion command.

So the first time you call the batch file %user% is undefined at execution time and the WMIC command fails with the error you noted in the question.

The second time you call the batch file %user% is defined (with the value from the previous execution and your batch file appears to work.

Note that if you enter a different user name the second time your batch file will return the wrong SID (it will use the user name entered the first time it was called).

You need to make the following changes:

  1. Add setlocal enabledelayedexpansion at the beginning of the batch file.

  2. Replace %util% with !util!

Modified batch file:

@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

Example Usage:

> test
DavidPostill

ntp

Administrator


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

Further Reading

DavidPostill

Posted 2017-07-04T15:59:29.570

Reputation: 118 938