Erro WMIC: nenhuma instância disponível após a primeira execução do meu script em lotes

2

Eu corro cmd.exe como administrador e executo este script, a primeira vez que eu o executo eu sempre recebo Instances Available , eu tenho que executá-lo uma segunda vez (às vezes 3-4 vezes) para realmente imprimir o SID. por quê?

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%
    
por user745333 04.07.2017 / 17:59

1 resposta

0

Eu tenho que executá-lo uma segunda vez (às vezes 3-4 vezes) para realmente imprimir o SID

Seu arquivo de lote não está usando setlocal ou delayedexpansion então só funcionará se %user% estiver definido no ambiente que está chamando o arquivo de lote.

Devido à falta de setlocal , as variáveis definidas dentro do arquivo de lote são vazadas no shell de comando de chamada e, em seguida, são utilizáveis na próxima vez em que o arquivo de lote for chamado.

Dentro do arquivo de lote (a primeira vez que é chamado)% user% não é utilizável dentro do arquivo de lote porque é referenciado dentro de um bloco de código ( 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.

Se você ativar a expansão atrasada :

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.

Portanto, a primeira vez que você chamar o arquivo em lote %user% é indefinido no momento da execução e o comando WMIC falhará com o erro que você anotou na pergunta.

A segunda vez que você chamar o arquivo de lote %user% é definido (com o valor da execução anterior e seu arquivo de lote aparece para funcionar.

Observe que, se você digitar um nome de usuário diferente na segunda vez que seu arquivo em lote retornará o SID errado (ele usará o nome de usuário inserido na primeira vez em que foi chamado).

Você precisa fazer as seguintes alterações:

  1. Adicione setlocal enabledelayedexpansion no início do arquivo de lote.

  2. Substitua %util% por !util!

Arquivo em lote modificado:

@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

Exemplo de uso:

> test
DavidPostill

ntp

Administrator


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

Leitura Adicional

por 04.07.2017 / 18:30

Tags