Пакетный файл, кажется, не вызывает другие командные файлы правильно - PullRequest
0 голосов
/ 04 октября 2019

Я пытаюсь создать командный файл, который вызывает другие командные файлы, которые разблокируют определенный диск на сервере при запуске. Я знаю, что скрипты разблокировки работают. Диск разблокируется, как и должно быть, если я их запускаю. Но когда я пытаюсь автоматизировать его, создавая другой пакетный сценарий для вызова этих сценариев на основе имени сервера, он не удается разблокировать. При запуске сценария вручную он сообщает мне, что вызываемый сценарий имеет неверный код разблокировки.

Я попытался добавить полное имя сервера, к которому я стремлюсь.

Вместо

If %computername% == "PartialServername*" Goto Servername

Я изменил его на

If %computername% == "Servername" Goto Servername

Я также попытался запустить его как:

If %computername% == "Servername" Call Servername.bat

И это сработало, но если у меня было несколько строк if.

Сервер Unlock.bat

pushd "\\servername\scripts\unlock scripts\"
If %computerName% == "PartialServerName1*" Goto Servername
:Servername Call Servername.Bat

Servername.bat

manage-bde -unlock d: -recoverypassword *Recovery key here*

Я ожидал, что он позвонитна пакетном файле и разблокировать диск, но вместо этого пакетный файл вызывает файл и затем говорит, что пароль восстановления неправильный.

Полный сценарий:

REM Created temporary network drive to the unlock scripts folder on vipre

pushd "\\scriptserver\unlock scripts\"

REM Checks the value of the Server name then goes to that section of the 
script REM to run the appropriate script
If %computerName% == "Bow*" Goto Bow
If %computerName% == "Del*" Goto Del
If %computerName% == "Fin*" Goto Fin
If %computerName% == "Gah*" Goto Gah
If %computerName% == "Gib*" Goto Gib
If %computerName% == "Kal*" Goto Kal
If %computerName% == "Ken*" Goto Ken
If %computerName% == "Lei*" Goto Lei
If %computerName% == "Lew*" Goto Lew
If %computerName% == "Lim*" Goto Lim
If %computerName% == "Loa*" Goto Loa
If %computerName% == "Mar*" Goto Mar
If %computerName% == "Ott*" Goto Ott
If %Computername% == "Pem*" Goto Pem
If %computerName% == "Ric*" Goto Ric
If %computerName% == "Sha*" Goto Sha
If %computerName% == "Wes*" Goto Wes
:Bow
Call Bow.bat
Call DistributionRestart.bat
popd
:Del
Call Del.bat
Call DistributionRestart.bat
popd
:Fin
Call Fin.bat
Call DistributionRestart.bat
popd
:Gah
Call Gah.bat
Call DistributionRestart.bat
popd
:Gib
Call Gib.bat
Call DistributionRestart.bat
popd
:Kal
Call Kal.bat
Call DistributionRestart.bat
popd
:Ken
Call Ken.bat
Call DistributionRestart.bat
popd
:Lei
Call Lei.bat
Call DistributionRestart.bat
popd
:Lew
Call Lew.bat
Call DistributionRestart.bat
popd
:Lim
Call Lim.bat
Call DistributionRestart.bat
popd
:Loa
Call Loa.bat
Call DistributionRestart.bat
popd
:Mar
Call Mar.bat
Call DistributionRestart.bat
popd
:Ott
Call Ott.bat
Call DistributionRestart.bat
popd
:Pem
Call Pem.bat
Call DistributionRestart.bat
popd
:Ric
Call Ric.bat
Call DistributionRestart.bat
popd
:Sha
Call Sha.bat
Call DistributionRestart.bat
popd
:Wes
Call Wes.bat
popd

Ответы [ 3 ]

1 голос
/ 04 октября 2019

Фундаментальное заблуждение:

В отличие от многих языков, пакетный режим не имеет понятия окончания «процедуры» - он просто продолжает выполнение построчно, пока не достигнет конца файла. Следовательно, вам нужно goto :eof после завершения основной строки, в противном случае выполнение будет продолжаться через код подпрограммы. :EOF - это предопределенная метка, понимаемая как CMD для обозначения end of file. Двоеточие обязательно .

for %%a in (Bow Del Fin ....) do If /i "%computerName:~0,3%" == "%%a" (
 if /i "%%a" == "Del" (
  Call delsub.bat
  Call DistributionRestart.bat
 ) else (
  Call %%a.bat
  Call DistributionRestart.bat
 )
)
popd

Здесь каждое из значений в списке сравнивается без учета регистра с первыми 3 символами computername, и если совпадение найдено,затем выполните соответствующие пакеты.

Поскольку del является ключевым словом - и опасным, delete Я также показал, как сделать исключение.

1 голос
/ 04 октября 2019

Computername является переменной окружения, поэтому сравнение должно проводиться без учета регистра. Используйте параметр /I, чтобы выполнить поиск без учета регистра


. Вам нужно иметь одинаковые кавычки с обеих сторон уравнения

IF/I "%computername%" == "<value>" ....
.    ^              ^    ^       ^
.    ^              ^    ^       ^

Обратите внимание на кавычки вокруг% computername% иоколо <value>.


Логика подстановочных знаков не будет работать, но простой метод - использовать сравнение подстрок. Вы всегда сравниваете 3 символа, так что вы можете изменить логику на что-то вроде:

if /I "%COMPUTERNAME:~0,3%" == "Bow" .....

Это начинается в начале (индекс 0) и создает строку длины 3, а затем сравнивает это с Bow, чтобы сделатьсравнение строк без учета регистра, где цитирование совпадает с обеих сторон

Рассмотрим следующий альтернативный скрипт

  1. один набор совпадающих pushd / popd
  2. Использование вспомогательных функций withDistribRestart и noDistribRestart для запуска соответствующих сценариев, где переданный параметр является именем выполняемого пакетного сценария
  3. Проверяет и сообщает неожиданные имена компьютеров

@ECHO OFF
GOTO :Main


REM =========================================================================
:Main
SETLOCAL
    SET "retVal=0"


    pushd "\\scriptserver\unlock scripts"


    if /I "%COMPUTERNAME:~0,3%" == "Bow" (
        CALL :withDistribRestart Bow
    ) else if /I "%COMPUTERNAME:~0,3%" == "Del" (
        CALL :withDistribRestart Del
    ) else if /I "%COMPUTERNAME:~0,3%" == "Fin" (
        CALL :withDistribRestart Fin
    ) else if /I "%COMPUTERNAME:~0,3%" == "Gah" (
        CALL :withDistribRestart Gah
    ) else if /I "%COMPUTERNAME:~0,3%" == "Gib" (
        CALL :withDistribRestart Gib
    ) else if /I "%COMPUTERNAME:~0,3%" == "Kal" (
        CALL :withDistribRestart Kal
    ) else if /I "%COMPUTERNAME:~0,3%" == "Ken" (
        CALL :withDistribRestart Ken
    ) else if /I "%COMPUTERNAME:~0,3%" == "Lei" (
        CALL :withDistribRestart Lei
    ) else if /I "%COMPUTERNAME:~0,3%" == "Lew" (
        CALL :withDistribRestart Lew
    ) else if /I "%COMPUTERNAME:~0,3%" == "Lim" (
        CALL :withDistribRestart Lim
    ) else if /I "%COMPUTERNAME:~0,3%" == "Loa" (
        CALL :withDistribRestart Loa
    ) else if /I "%COMPUTERNAME:~0,3%" == "Mar" (
        CALL :withDistribRestart Mar
    ) else if /I "%COMPUTERNAME:~0,3%" == "Ott" (
        CALL :withDistribRestart Ott
    ) else if /I "%COMPUTERNAME:~0,3%" == "Pem" (
        CALL :withDistribRestart Pem
    ) else if /I "%COMPUTERNAME:~0,3%" == "Ric" (
        CALL :withDistribRestart Ric
    ) else if /I "%COMPUTERNAME:~0,3%" == "Sha" (
        CALL :withDistribRestart Sha
    ) else if /I "%COMPUTERNAME:~0,3%" == "Wes" (
        CALL :noDistribRestart Wes
    ) else (
        ECHO Unexpected COMPUTERNAME '"%COMPUTERNAME%"'
        SET "retVal=1"
    )

    popd
(ENDLOCAL
 EXIT /B %retVal%)



REM ========================================================================
:withDistribRestart
SETLOCAL
    SET "PREFIX=%~1"

    CALL "%PREFIX%.bat"
    CALL "DistributionRestart.bat"
(ENDLOCAL
 EXIT /B 0)




REM ========================================================================
:noDistribRestart
SETLOCAL
    SET "PREFIX=%~1"

    CALL "%PREFIX%.bat"
(ENDLOCAL
 EXIT /B 0)
0 голосов
/ 05 октября 2019

Вы можете заменить все эти If команды на:

GoTo %ComputerName:~,3% 2>NUL||Exit /B

Однако вы можете выполнить весь этот скрипт также в одной строке:

@PushD "\\scriptserver\unlock scripts" 2>NUL&&For %%A In (Bow Del Fin Gah Gib Kal Ken Lei Lew Lim Loa Mar Ott Pem Ric Sha Wes)Do @If /I "%ComputerName:~,3%"=="%%A" (Call "%%A.bat"&If /I Not "%%A"=="Wes" Call "DistributionRestart.bat")

Вы можетекурс разделен на несколько строк для удобства чтения:

@Echo Off
PushD "\\scriptserver\unlock scripts" 2>NUL||Exit /B
For %%A In (Bow Del Fin Gah Gib Kal Ken Lei Lew Lim Loa Mar Ott Pem Ric Sha Wes
)Do If /I "%ComputerName:~,3%"=="%%A" (Call "%%A.bat"
    If /I Not "%%A"=="Wes" Call "DistributionRestart.bat")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...