Работы С Нами BAT/CMD скрипт я могу просто использовать «msiexec /i /quiet /norestart» и затем проверьте %errorlevel% за результат.
Работы С Нами VBScript , С использованием Wscript.Shell объект Run() методом, я могу получить такой результат:
«result = oShell.Run(«msiexec /i . «, 1, True)»
Как я могу сделать это с помощью PowerShell?
любой образец с полным исходным кодом? — Kiquenet
3 ответы
Я бы обернул это в Start-Process и использовал свойство ExitCode полученного объекта процесса. Например
(Start-Process -FilePath «msiexec.exe» -ArgumentList «>» -Wait -Passthru).ExitCode
Вот что я искал! Однако это «ArgumentList», а не «ArgumentsList», но в любом случае вы ответили на вопрос — спасибо! — Скаттербрайнз
Заметки; 1. Внутри указанного в кавычках -ArgumentList аргументы разделяются пробелами, а для хранения таких элементов, как путь с пробелами в имени, можно использовать одинарные кавычки. 2.ExitCode становится доступным, только если все порожденные окна закрыты; 3. Я использую PS v4.0. — AnneTheAgile
Как включить выполнение сценариев PowerShell в Windows 10
Если вы не можете использовать цитируемый -ArgumentList » ‘$arg1 with spaces’ arg2″ вы можете разделить запятыми несколько аргументов -ArgumentList «$arg1 with spaces», arg2 , как только он перестанет находить запятые, PowerShell предполагает, что следующим является другой позиционный аргумент или что-то вроде -Wait он просто возобновит обработку названных аргументов. — dragon788
$LastExitCode
в зависимости от того, что вам нужно. Первое — целое число, второе — просто логическое. Более того, $LastExitCode заполняется только для запущенных собственных программ, а $? обычно сообщает, был ли последний запуск команды успешным или нет, поэтому он также будет установлен для командлетов.
PS Home:> cmd /c «echo foo»; $?,$LASTEXITCODE foo True 0 PS Home:> cmd /c «ech foo»; $?,$LASTEXITCODE ‘ech’ is not recognized as an internal or external command, operable program or batch file. False 1
Вы также можете использовать комплект развертывания приложений PowerShell, который предоставляет несколько возможностей.
Тогда вы можете использовать, например,
Execute-MSI -Action ‘Install’ -Path «$dirFilesyour.msi» -AddParameters «INSTALLFOLDER=C:$appFolder»
Не тот ответ, который вы ищете? Просмотрите другие вопросы с метками powershell return-value exit-code windows-installer or задайте свой вопрос.
ADV
Связанные вопросы
Последние вопросы
Связанные теги
stackovergo.com 2020–2023, под лицензией куб.см по-са 3.0 с указанием авторства. | Персональные данные | Cookies политики
Источник: stackovergo.com
Eugeneer’s Media Cloud World
Блог творческого ИТ-практика — возьми свою мысль и придай ей ускорение идеи! В фокусе: сети, безопасность, виртуализация, web, мультимедиа.
How To Force A PowerShell Script To Return A Certain Exit Code
Главная
А А Friday, 8 December 2017
Варианты перехвата ошибок в PowerShell.
Всем привет.
В предыдущих двух постах были подробно изложены методы отлова критических и некритических ошибок при работе с PowerShell. Но я решил что будет несправедливым не отметить самые основные моменты, которые возникают в работе если что-то пошло не так. Т.е. переменные и обьекты в PowerShell которые содержат первичную информацию о работе нашего скрипта. Речь пойдет об объекте ErrorRecord, о переменной $Error, о мониторинге возникновения ошибки c помощью переменной $? и кодов возврата, а также упомянем командлет Set-PSDebug и точки прерывания. Поможет нам в этом замечательная книга Попова А. В. «Введение в Windows PowerShell» — СПб.: БХВ-Петербург, 2009.
1. Объект ErrorRecord и поток ошибок.
В PowerShell информация о возникающих ошибках записывается в поток ошибок, который по умолчанию отображается на экране, например:
PS C:> dir «C:Folder doesn’t exist»
Get-ChildItem : Не удается найти путь «C:Folder doesn’t exist»,
так как он не существует.
В строка:1 знак:4
+ dir
Поток ошибок можно перенаправить в текстовый файл с помощью специального оператора 2>, например:
PS C:> dir «C:Folder doesn’t exist» 2>err.txt
Проверим теперь содержимое файла err.txt:
PS C:> Get-Content err.txt
Get-ChildItem : Не удается найти путь «C:Folder doesn’t exist»,
так как он не существует.
В строка:1 знак:4
+ dir err.txt
Как видите, в файл err.txt полностью записалось сообщение об ошибке, однако никакой дополнительной информации не появилось.
Где произошла ошибка смотрим так
PS C:> $err.InvocationInfo
MyCommand : Get-ChildItem
ScriptLineNumber : 1
OffsetInLine : -2147483648
ScriptName :
Line : $err = dir «C:Folder doesn’t exist» 2>1
InvocationName : dir
PipelineLength : 1
PipelinePosition : 1
Хотя этот вывод даст нам место скрипта(или непсредственного ввода)
где ошибку интепретирует сама PowerShell, истинное место проблемы надо будет
искать самим.
2. Специальная переменная $Error.
В PowerShell имеется специальная переменная $Error, которая содержит коллекцию (массив) объектов ErrorRecord, соответствующих ошибкам, возникавшим в текущем сеансе работы. Максимальное количество элементов в данной коллекции задается значением переменной $MaximumErrorCount (по умолчанию это 256):
PS C:> $MaximumErrorCount
256
После заполнения массива $Error объекты для вновь возникающих ошибок будут заменять объекты, соответствующие старым ошибкам. Возникновение каждой новой ошибки приводит к смещению элементов в массиве $Error: объект для последней ошибки хранится в первом элементе ($Error[0]), объект для предыдущей ошибки — во втором элементе ($Error[1]) и т. д.
Убедимся, что элемент $Error[0] имеет тип ErrorRecord, и выведем содержимое этого элемента:
PS C:> $Error[0].GetType().FullName
System.Management.Automation.ErrorRecord
PS C:> $Error[0]
Get-ChildItem : Не удается найти путь «C:Несуществующий каталог»,
так как он не существует.
В строка:1 знак:4
+ dir Естественно, мы можем обращаться ко всем свойствам объекта ErrorRecord:
PS C:> $Error[0].Exception
Не удается найти путь «C:Несуществующий каталог», так как он не существует.
Повторим вывод свойства InvocationInfo
PS C:> $Error[0].InvocationInfo
MyCommand : Get-ChildItem
ScriptLineNumber : 1
OffsetInLine : -2147483648
ScriptName :
Line : $err = dir «C:Folder doesn’t exist» 2>1
InvocationName : dir
PipelineLength : 1
PipelinePosition : 1
3. Мониторинг возникновения ошибки переменной $?.
В PowerShell имеется логическая переменная $?, которая равна $True, если последняя выполняемая операция завершена успешно, и $False, если во время выполнения последней
операции возникла ошибка. Такая же существует и в Linux.) Например, если выполнить командлет Get-Item для заведомо существующего каталога, то значение переменной $? будет равно $True:
PS C:> Get-Item С:
Каталог:
Mode LastWriteTime Length Name
—- ————- —— —-
d—hs 21.03.2016 12:00 C:
Если же выполнить этот же командлет для несуществующего каталога, то значение переменной $? будет равно $False:
PS C:> Get-Item С:321
Get-Item : Не удается найти путь «C:321», так как он не существует.
В строка:1 знак:9
Глава 9. Обработка ошибок и отладка 183
+ Get-Item PS C:> $?
False
4. Мониторинг возникновения ошибки по коду возврата.
Для внешних команд Windows и сценариев PowerShell определено понятие кода возврата (напомним, что для сценариев PowerShell этот код можно установить с помощью инструкции Exit). В операционной системе код возврата последней команды доступен через переменную среды %ERRORLEVEL%; в оболочке PowerShell данный код возврата хранится в специальной переменной $LASTEXITCODE. При этом, если код возврата равен нулю, то переменной $? присваивается значение $True. Если же код возврата не равен нулю, то считается, что при выполнении данной команды произошла ошибка, и переменной $? присваивается значение $False.
В качестве примера выполним команду интерпретатора cmd.exe, которая устанавливает нулевой код возврата. Для этого можно запустить cmd.exe с ключом /c (выполнить команду и завершить работу интерпретатора) и указать для исполнения команду exit 0:
PS C:> cmd /c exit 0
Проверим значения переменных $LASTEXITCODE и $?:
PS C:> $LASTEXITCODE
0
PS C:> $?
True
Теперь выполним команду интерпретатора cmd.exe с ненулевым кодом возврата (пусть, например, код возврата равен 10):
PS C:> cmd /c exit 10
Вновь проверим переменные $LASTEXITCODE и $?:
PS C:> $?
False
PS C:> $LASTEXITCODE
10
5. Командлет Set-PSDebug и точки прерывания.
Процесс поиска ошибок в сценариях неразрывно связан с отладкой. Поэтому нам стоит упомянуть что основным встроенным инструментом для отладки сценариев является командлет Set-PSDebug. Параметры этого командлета позволяют включить режимы трассировки и пошагового выполнения команд, а также режим обязательного объявления переменных:
-Trace 0 Отключение трассировки
-Trace 1 Включение основного режима трассировки
-Trace 2 Включение полного режима трассировки
-Step Включение режима пошагового выполнения
-Strict Включение режима обязательного объявления переменных
-Off Отключение всех механизмов отладки.
Примеры приводить не буду, назначение ключей очевидно из их названия. Самым интересным является режим пошагового выполнения -Step, который позволяет в любой момент вызвать вложенную командную строку для анализа или изменения состояния интерпретатора. Однако отлаживать более-менее большие сценарии с помощью данного метода часто оказывается неудобно, так как для запуска вложенного сеанса в определенной строке сценария придется каждый раз добираться до этой строки с самого начала сценария (каждую команду при этом
нужно выполнять, нажимая клавишу ).
Гораздо удобнее было бы использовать точки прерывания, позволяющие запускать сценарий в автоматическом режиме и приостанавливать выполнение на нужной команде. В PowerShell аналогом установки точки прерывания можно считать вызов метода $Host.EnterNestedPrompt(), например:
PS C:> for ($i=0; $i -lt 10; $i++) >> «i = $i»
>> if ($i -eq 5) >> «Моя точка прерывания»
>> $Host.EnterNestedPrompt()
>> >
>> >
>>
i = 0
i = 1
i = 2
i = 3
i = 4
i = 5
Моя точка прерывания
PS C:>>>
В данном примере на пятой итерации цикла выводится строка «Моя точка прерывания» и вызывается метод $Host.EnterNestedPrompt(). В результате выполнение цикла приостанавливается, и мы попадаем во вложенную командную строку (вид приглашения изменяется на >>>).
Выход из вложенного сеанса с помощью инструкции Exit:
PS C:>>> Exit
PS C:>
Источник: nyukers.blogspot.com
Обработка ошибок с исключениями в Powershell с Try и Catch
В Powershell существует несколько уровней ошибок и несколько способов их обработать. Проблемы одного уровня (Non-Terminating Errors) можно решить с помощью привычных для Powershell команд. Другой уровень ошибок (Terminating Errors) решается с помощью исключений (Exceptions) стандартного, для большинства языков, блока в виде Try, Catch и Finally.
Навигация по посту
- Как Powershell обрабатывает ошибки
- Автоматические переменные $Error
- Свойства объекта $Error
- Методы объекта $Error
- Критические ошибки (Terminating Errors)
- Не критические ошибки (Non-Terminating Errors)
- Параметр ErrorVariable
- Приоритет с $ErrorActionPreference
- Использование параметра ErrorAction
- Catch для всех исключений
- Создание отдельных исключений
- Выброс с throw
- Использование Write-Error
Как Powershell обрабатывает ошибки
До рассмотрения основных методов посмотрим на теоретическую часть.
Автоматические переменные $Error
В Powershell существует множество переменных, которые создаются автоматически. Одна из таких переменных — $Error хранит в себе все ошибки за текущий сеанс PS. Например так я выведу количество ошибок и их сообщение за весь сеанс:
Get-TestTest $Error $Error.Count
При отсутствии каких либо ошибок мы бы получили пустой ответ, а счетчик будет равняться 0:
Переменная $Error являет массивом и мы можем по нему пройтись или обратиться по индексу что бы найти нужную ошибку:
$Error[0] foreach ($item in $Error)
Свойства объекта $Error
Так же как и все что создается в Powershell переменная $Error так же имеет свойства (дополнительную информацию) и методы. Названия свойств и методов можно увидеть через команду Get-Member:
$Error | Get-Member
Например, с помощью свойства InvocationInfo, мы можем вывести более структурный отчет об ошибки:
$Error[0].InvocationInfo
Методы объекта $Error
Например мы можем очистить логи ошибок используя clear:
$Error.clear()
Критические ошибки (Terminating Errors)
Критические (завершающие) ошибки останавливают работу скрипта. Например это может быть ошибка в названии командлета или параметра. В следующем примере команда должна была бы вернуть процессы «svchost» дважды, но из-за использования несуществующего параметра ‘—Error’ не выполнится вообще:
‘svchost’,’svchost’ | % —Error
Не критические ошибки (Non-Terminating Errors)
Не критические (не завершающие) ошибки не остановят работу скрипта полностью, но могут вывести сообщение об этом. Это могут быть ошибки не в самих командлетах Powershell, а в значениях, которые вы используете. На предыдущем примере мы можем допустить опечатку в названии процессов, но команда все равно продолжит работу:
‘svchost111′,’svchost’ | %
Как видно у нас появилась информация о проблеме с первым процессом ‘svchost111’, так как его не существует. Обычный процесс ‘svchost’ он у нас вывелся корректно.
Параметр ErrorVariable
Если вы не хотите использовать автоматическую переменную $Error, то сможете определять свою переменную индивидуально для каждой команды. Эта переменная определяется в параметре ErrorVariable:
‘svchost111′,’svchost’ | % -ErrorVariable my_err_var $my_err_var
Переменная будет иметь те же свойства, что и автоматическая:
$my_err_var.InvocationInfo
Вам так же будет интересно:
Повторное использование логина и пароля в Powershell с Get-Credential и их шифрование
Обработка некритических ошибок
У нас есть два способа определения последующих действий при ‘Non-Terminating Errors’. Это правило можно задать локально и глобально (в рамках сессии). Мы сможем полностью остановить работу скрипта или вообще отменить вывод ошибок.
Приоритет ошибок с $ErrorActionPreference
Еще одна встроенная переменная в Powershell $ErrorActionPreference глобально определяет что должно случится, если у нас появится обычная ошибка. По умолчанию это значение равно ‘Continue’, что значит «вывести информацию об ошибке и продолжить работу»:
$ErrorActionPreference
Если мы поменяем значение этой переменной на ‘Stop’, то поведение скриптов и команд будет аналогично критичным ошибкам. Вы можете убедиться в этом на прошлом скрипте с неверным именем процесса:
$ErrorActionPreference = ‘Stop’ ‘svchost111′,’svchost’ | %
Т.е. скрипт был остановлен в самом начале. Значение переменной будет храниться до момента завершения сессии Powershell. При перезагрузке компьютера, например, вернется значение по умолчанию.
Ниже значение, которые мы можем установить в переменной $ErrorActionPreference:
- Continue — вывод ошибки и продолжение работы;
- Inquire — приостановит работу скрипта и спросит о дальнейших действиях;
- SilentlyContinue — скрипт продолжит свою работу без вывода ошибок;
- Stop — остановка скрипта при первой ошибке.
Самый частый параметр, который мне приходится использовать — SilentlyContinue:
$ErrorActionPreference = ‘SilentlyContinue’ ‘svchost111′,’svchost’ | %
Использование параметра ErrorAction
Переменная $ErrorActionPreference указывает глобальный приоритет, но мы можем определить такую логику в рамках команды с параметром ErrorAction. Этот параметр имеет больший приоритет чем $ErrorActionPreference. В следующем примере, глобальная переменная определяет полную остановку скрипта, а в параметр ErrorAction говорит «не выводить ошибок и продолжить работу»:
$ErrorActionPreference = ‘Stop’ ‘svchost111′,’svchost’ | %
Кроме ‘SilentlyContinue’ мы можем указывать те же параметры, что и в переменной $ErrorActionPreference.
Значение Stop, в обоих случаях, делает ошибку критической.
Обработка критических ошибок и исключений с Try, Catch и Finally
Когда мы ожидаем получить какую-то ошибку и добавить логику нужно использовать Try и Catch. Например, если в вариантах выше мы определяли нужно ли нам отображать ошибку или останавливать скрипт, то теперь сможем изменить выполнение скрипта или команды вообще. Блок Try и Catch работает только с критическими ошибками и в случаях если $ErrorActionPreference или ErrorAction имеют значение Stop.
Например, если с помощью Powershell мы пытаемся подключиться к множеству компьютеров один из них может быть выключен — это приведет к ошибке. Так как эту ситуацию мы можем предвидеть, то мы можем обработать ее. Процесс обработки ошибок называется исключением (Exception).
Синтаксис и логика работы команды следующая:
try < # Пытаемся подключиться к компьютеру >catch [Имя исключения 1],[Имя исключения 2] < # Раз компьютер не доступен, сделать то-то >finally
Блок try мониторит ошибки и если она произойдет, то она добавится в переменную $Error и скрипт перейдет к блоку Catch. Так как ошибки могут быть разные (нет доступа, нет сети, блокирует правило фаервола и т.д.) то мы можем прописывать один блок Try и несколько Catch:
try < # Пытаемся подключится >catch [‘Нет сети’][‘Блокирует фаервол’] < # Записываем в файл >catch [‘Нет прав на подключение’]
Сам блок finally — не обязательный и используется редко. Он выполняется самым последним, после try и catch и не имеет каких-то условий.
Catch для всех типов исключений
Как и было показано выше мы можем использовать блок Catch для конкретного типа ошибок, например при проблемах с доступом. Если в этом месте ничего не указывать — в этом блоке будут обрабатываться все варианты ошибок:
try < ‘svchost111′,’svchost’ | % > catch
Такой подход не рекомендуется использовать часто, так как вы можете пропустить что-то важное.