Но одним из основных недостатков этого является то, что уровни ошибок и среда больше не доступны.
Самый простой способ заставить команду PowerShell, вызываемую через интерфейс командной строки PowerShell, сообщать о ненулевом коде выходавыдает ошибку завершения скрипта (завершения потока), которая приводит к коду ошибки 1
, который ваш пакетный файл может проверить:
@echo off
:: # Simulate a failing CIM call
powershell -c "$ErrorActionPreference='Stop'; Get-CimInstance Win32_NoSuchClass"
:: # Exit, if the PowerShell command failed.
if ERRORLEVEL 1 echo Error: Get-CimInstance failed>&2 & exit /b %ERRORLEVEL%
echo Moving on...
$ErrorActionPreference='Stop'
в начале команды обеспечиваетчто любая последующая ошибка становится оканчивающейся скриптом.
Чтобы выборочно игнорировать не прерывающиеся ошибки, используйте -ErrorAction Ignore
по-отдельности для команды.
Если ошибок не возникает, код выхода неявно 0
.
Обработка ошибок в PowerShell очень сложна;см. эту проблему GitHub для получения полной сводки.
Примечание:
Собственные команды PowerShell, такие как Get-CimInstance
, не устанавливают выходкоды;лучшее, что вы можете сделать, это сопоставить ошибки с кодом выхода 1
и успешно завершить с кодом выхода 0
.
Если вы вызываете внешние программы из PowerShell, их код выхода отображаетсяв автоматической переменной $LASTEXITCODE
;вы можете использовать exit $LASTEXITCODE
для передачи этого кода завершения из командной строки PowerShell;однако обычно вы можете просто напрямую вызывать внешние программы из своего пакетного файла - обход через PowerShell не требуется.
А изменения, внесенные в среду в команде powershell, делаютне распространяются на командный файл.
True, команда PowerShell неизменно выполняется в дочернем процессе , среда которого не влияет на вызывающий процесс.
Обычно:
Захватывать выводить из команды PowerShell в файл или обрабатывать его в памяти с помощью цикла for /f
(см. Пример ниже) - если не передать выходные данные - достаточно.
Если вам действительно нужно изменить среду вызывающего пакетного файла , команда PowerShell выведет данные для этих модификаций и примените их в командном файле.
- Например, если вы хотите, чтобы ваша команда PowerShell устанавливала переменные среды, сделайте так, чтобы она выводила
<name>=<value>
пар строк, которыеПакетный файл можно использовать для установки этих переменных.
Пример настройки вывода команды PowerShell для анализа в пакетном файле с помощью for /f
;обратите внимание, что цитирование может быть хитрым:
@echo off
:: # Get the .Name and .MaxClockSpeed property values from the Win32_Processor instance.
for /f "tokens=1,* delims==" %%i in ('powershell -c "$ErrorActionPreference='Stop'; Get-CimInstance Win32_Processor | %% { foreach ($n in 'Name', 'MaxClockSpeed') { \""$n=$($_.$n)\"" } }"') do (
echo [%%i]=[%%j]
)
:: # Exit, if the PowerShell command failed.
if ERRORLEVEL 1 echo Error: Get-CimInstance failed>&2 & exit /b %ERRORLEVEL%
Выше приведено что-то вроде:
[Name]=[Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz]
[MaxClockSpeed]=[2304]