Problemas ao elevar permissões durante a execução de um arquivo em lote (CMD)

1

Eu coloquei um arquivo de lote (CMD) que usamos para verificar várias coisas em servidores selecionados. O que é postado abaixo é quase tudo (menos informações sensíveis). Se iniciado com a linha de comando adequada, o arquivo em lote continuará a verificar o dia e a hora em que é iniciado. Dessa forma, podemos colocá-lo na pasta STARTUP em nossos servidores e quando efetuamos login, ele é executado e, se o usuário efetuar login em um dia útil entre 06:45 - 07:30, determinadas verificações são feitas (ou seja, externo aplicativos são lançados, etc.). Seletivamente, o aplicativo adequado é executado com base em variáveis de ambiente, como COMPUTERNAME, USERNAME (que foi removido no código abaixo), etc.

Um dos processos que precisamos executar requer a elevação de direitos (IISRESET). Para realizar isso em um arquivo de lote, usei o exemplo mostrado por Matt (obrigado) encontrado em link . Eu não queria postar nesse tópico porque esse é um novo tópico. No arquivo de lote que forneci abaixo, ele funciona corretamente como está (sem garantias ou garantias implícitas). Mas se eu remover os caracteres de "comentário" (os dois-pontos duplos) mudando:

    :BEGIN
    If %COMPUTERNAME%==SERVER1 explorer.exe "c:\queue"
    :: If %COMPUTERNAME%==SERVER1 Goto CHECKPRIVILEGES

    If %COMPUTERNAME%==SERVER2 explorer.exe "c:\queue"
    :: If %COMPUTERNAME%==SERVER2 Goto CHECKPRIVILEGES

    :COMMON

... (em) ...

    :BEGIN
    If %COMPUTERNAME%==SERVER1 explorer.exe "c:\queue"
    If %COMPUTERNAME%==SERVER1 Goto CHECKPRIVILEGES

    If %COMPUTERNAME%==SERVER2 explorer.exe "c:\queue"
    If %COMPUTERNAME%==SERVER2 Goto CHECKPRIVILEGES

    :COMMON

... o arquivo de lote não é executado corretamente. Quando removo os comentários das duas linhas, o arquivo em lotes não avalia mais as variáveis corretamente (seja executado manualmente ou como parte do processo STARTUP). Mesmo que o arquivo em lotes indique:

    If %COMPUTERNAME%==SERVER1
    If %COMPUTERNAME%==SERVER2

… o comando associado a SERVER1 é executado corretamente, mas o SERVER2 executa os comandos associados a ambos, SERVER1 e SERVER2. Em seguida, o arquivo em lotes é interrompido e nunca executa nenhum comando na seção COMMON:

    :COMMON
    explorer.exe /e,
    Start services.msc

… etc…

Eu testei vários cenários e sei que estou negligenciando algo simples bem na minha frente. Alguém pode ver o que há de errado com o arquivo de lote abaixo?

Obrigado

----------------------------------------------- --------------

Arquivo de lote completo:

    @Echo Off

    ::  ***** If not started using "-Login" with the cmd line then we won't even check the day or time *****
    ::  ***** We won't even consider what day or time it is if we run this CMD file manually *****
    Set LaunchString=%1%
    If [%LaunchString%] equ [] Goto BEGIN    Rem ***** No parameters given *****
    Call :UPCASE LaunchString
    If not %LaunchString% equ -LOGIN Goto BEGIN

    ::  ***** See if we're running on a normal business weekday *****
    ::  ***** That way we can put this in server startup to run automatically at login during certain times *****
    For /F "tokens=1 delims= " %%A IN ('Date /t') DO @(Set DayName=%%A)
    If %DayName:~0,3% equ Mon Goto CONTINUE
    If %DayName:~0,3% equ Tue Goto CONTINUE
    If %DayName:~0,3% equ Wed Goto CONTINUE
    If %DayName:~0,3% equ Thu Goto CONTINUE
    If %DayName:~0,3% equ Fri Goto CONTINUE
    Goto FINISH        Rem ***** Not a business day so exit *****

    :CONTINUE
    :: Check if the time is between 06:45 and 07:30 and if not then exit otherwise continue processing
    Setlocal enableextensions enabledelayedexpansion
    Set tm=%time%
    Set hh=!tm:~0,2!
    Set mm=!tm:~3,2!
    If !hh! equ 6 (                :: Hour is 6 (i.e., 06:xx AM)
        If not !mm! gtr 44 (            ::   - Since hour is 6, are minutes greater than 44 (i.e., after 06:45)?
            Goto FINISH
        )
    ) else If !hh! equ 7 (                :: Hour is 7 (i.e., 07:xx AM)
        If not !mm! lss 30 (            ::   - Since hour is 7, are minutes less than 31 (i.e., before 07:30)?
            Goto FINISH
        )
    ) else Goto FINISH
    Endlocal

    :: If manually launched without command line argument then we start here (no day or time check)
    :BEGIN
    If %COMPUTERNAME%==SERVER1 explorer.exe "c:\queue"
    :: If %COMPUTERNAME%==SERVER1 Goto CHECKPRIVILEGES

    If %COMPUTERNAME%==SERVER2 explorer.exe "c:\queue"
    :: If %COMPUTERNAME%==SERVER2 Goto CHECKPRIVILEGES

    :COMMON
    explorer.exe /e,
    Start services.msc

    ::  ***** Check if test file exists *****
    If Exist "c:\test.log" Start c:\programA.exe
    If Exist "d:\test.log" Start c:\programB.exe

    :FINISH
    Exit /B
    Goto:EOF

    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

    :: Subroutine - Convert a variable VALUE to all UPPER CASE.
    :UPCASE
    For %%i IN     ("a=A" "b=B" "c=C" "d=D" "e=E" "f=F" "g=G" "h=H" "i=I" "j=J" "k=K" "l=L" "m=M" "n=N" "o=O" "p=P" "q=Q" "r=R" "s=S" "t=T" "u=U" "v=V" "w=W" "x=X" "y=Y" "z=Z") DO Call Set "%1=%%%1:%%~i%%"
    Goto :EOF

    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

    :: Subroutine - Elevate permissions to run IISRESET
    :CHECKPRIVILEGES
    Net FILE 1>NUL 2>NUL
    If '%errorlevel%' == '0' ( Goto gotPrivileges ) else ( Goto getPrivileges )

    :GETPRIVILEGES
    If '%1'=='ELEV' (shift & goto gotPrivileges)
    Setlocal DisableDelayedExpansion
    Set "batchPath=%~0"
    Setlocal EnableDelayedExpansion
    ECHO Set UAC = CreateObject^("Shell.Application"^) > "%temp%\OEgetPrivileges.vbs"
    ECHO UAC.ShellExecute "!batchPath!", "ELEV", "", "runas", 1 >> "%temp%\OEgetPrivileges.vbs"
    "%temp%\OEgetPrivileges.vbs"
    :: Del "%temp%\OEgetPrivileges.vbs"
    Exit /B

    :GOTPRIVILEGES
    Setlocal & pushd .
    CMD /k iisreset
    Goto :EOF
    
por STGdb 21.11.2013 / 19:50

1 resposta

0

Agradeço muito a todos por sua contribuição e aconselhamento. Sim, eu normalmente sigo os padrões em qualquer um dos meus códigos (sempre usando todas as letras minúsculas ou sempre maiúsculas para as etiquetas). Obrigado por pegar isso.

Então eu descobri qual era o meu problema. Primeiro, o que está acontecendo no meu arquivo de lote é que ele testa se a elevação é necessária e, em caso afirmativo, ele executa um script para obter acesso elevado. Eu estava tão focado na parte de elevação que nem estava pensando no resto do arquivo de lote (e como ele avalia via uma variável de linha de comando). Como ele avalia o uso de variáveis de linha de comando, isso fazia com que o restante da execução do arquivo em lote falhasse. Então eu peguei a parte que eleva os privilégios e reescrevei. Eu publiquei o código atualizado abaixo para que qualquer pessoa que precise dele também possa usá-lo. O código abaixo eleva (se necessário) e executa o IISRESET elevado. Acabou de adicionar / atualizar conforme necessário.

O "não retornar" para a parte de rótulos que eu estava falando na minha postagem original, foi porque eu estava usando o Goto e não o Call. Acho que eu tenho começado na tela por muito tempo ...

Obrigado novamente !!

:CHECKPRIVILEGES
Setlocal
Set PrivLaunchCmd=%temp%\Cmd2Run.CMD
ECHO "%SystemRoot%\System32\iisreset.exe" > "%PrivLaunchCmd%"
Net FILE 1>NUL 2>NUL
If '%errorlevel%' == '0' Goto GOTPRIVILEGES

:GETPRIVILEGES
ECHO Set UAC = CreateObject^("Shell.Application"^) > "%temp%\OEgetPrivileges.vbs"
ECHO UAC.ShellExecute "%PrivLaunchCmd%", "ELEV", "", "runas", 1 >> "%temp%\OEgetPrivileges.vbs"
Call "%temp%\OEgetPrivileges.vbs"
Del "%temp%\OEgetPrivileges.vbs"
Del "%PrivLaunchCmd%"
Endlocal
Goto :EOF

:GOTPRIVILEGES
Call "%PrivLaunchCmd%"
Del "%PrivLaunchCmd%"
Endlocal
Goto :EOF
    
por 22.11.2013 / 21:05