-ErrorVariable

Продолжаем «работу над ошибками»🙂 В прошлый раз я рассказал о параметре командлетов -ErrorAction, а сегодня займёмся его соседом -ErrorVariable. Как можно догадаться из названия, он указывает переменную в которую будет помещён объект ошибки (да, в PowerShell даже ошибки являются объектами😉 ). Но тут возникает одна популярная ошибка. Обычно все (в том числе и я😉 ) пробуют указать в качестве аргумента этой команде переменную😉

[PS <24> C:\Root] Get-Process -id 1234 -ErrorVariable $MyError
Get-Process : Cannot find a process with the process identifier 1234.
At line:1 char:12
+ Get-Process <<<<  -id 1234 -ErrorVariable $MyError

Казалось бы всё правильно, произошла ошибка, и соответствующий объект был помещен в переменную $MyError? Ан нет, такой переменной даже не существует. В чём же дело? А в том что парсер PowerShell’а, разбирая эту строчку увидел символ $ и понял что следом за ним идет переменная, которую надо преобразовать в её значение перед передачей команде (логично ведь?😉 ). А так как такой переменной не существует, PowerShell поступил так же как он обычно поступает с неназначенными переменными — передал вместо неё … ничего. То есть параметр -ErrorVariable не получил названия переменной в которую ему следовало поместить ошибку. Думаю уже понятно что для того чтобы этого не произошло, надо указывать просто название переменной, без символа $:

[PS <25> C:\Root] Get-Process -id 1234 -ErrorVariable MyError
Get-Process : Cannot find a process with the process identifier 1234.
At line:1 char:12
+ Get-Process <<<<  -id 1234 -ErrorVariable MyError
[PS <26> C:\Root] $MyError
Get-Process : Cannot find a process with the process identifier 1234.
At line:1 char:12
+ Get-Process <<<<  -id 1234 -ErrorVariable MyError

Итак объект с ошибкой у нас есть, что же с ним можно делать дальше?

Нет! Ни в коем случае не парсить! Хотя это и можно сделать — это было бы в корне неправильно. У нас в руках полноценный объект, с очень полезными свойстами к которым можно обращаться без всяких заморочек с разбором текста (который кстати может отличатся не только у разных ошибок, но и при использовании разных языков).

И тут возникает вторая тонкость. При попытке посмотреть свойства ошибки перенаправив её на команду Format-List * нас ждёт жестокий облом:

[PS <27> C:\Root] $MyError | Format-List *
Get-Process : Cannot find a process with the process identifier 1234.
At line:1 char:12
+ Get-Process <<<<  -id 1234 -ErrorVariable MyError

На выходе получился не ожидаемый список всех свойств, а тот же самый текст. Чтобы этого не случилось, надо добавить к Format-List параметр -Force:

[PS <28> C:\Root] $MyError | Format-List * -Force

Exception             : Microsoft.PowerShell.Commands.ProcessCommandException: Cannot find a process with the process identifier 1234.
TargetObject          : 1234
CategoryInfo          : ObjectNotFound: (1234:Int32) [Get-Process], ProcessCommandException
FullyQualifiedErrorId : NoProcessFoundForGivenId,Microsoft.PowerShell.Commands.GetProcessCommand
ErrorDetails          :
InvocationInfo        : System.Management.Automation.InvocationInfo

Еще стоит обратить внимание на то что $MyError является массивом. В случае если при выполнении команды произойдет несколько ошибок — все они будут помещены в переменную, и ни одна не потеряется. И поэтому если мы хотим посмотреть например свойство InvocationInfo то следует указать индекс элемента:

[PS <29> C:\Root] $MyError[0].InvocationInfo

MyCommand             : Get-Process
CommandLineParameters : {[Id, System.Int32[]]}
ScriptLineNumber      : 1
OffsetInLine          : 12
ScriptName            :
Line                  : Get-Process -id 1234 -ErrorVariable MyError
PositionMessage       :
                        At line:1 char:12
                        + Get-Process <<<<  -id 1234 -ErrorVariable MyError
InvocationName        : Get-Process
PipelineLength        : 1
PipelinePosition      : 1
ExpectingInput        : False
CommandOrigin         : Runspace

Ну и конечно можно получить только значение конкретного свойства. И без всякого парсинга😉 Например позицию в строке на которой произошла ошибка:

[PS <30> C:\Root] $MyError[0].InvocationInfo.OffsetInLine
12

Это разумеется еще не всё про ошибки, ждите продолжений😉

Опубликовано в Learn, PowerShell, Scripting, Tips. 1 Comment »

Один ответ to “-ErrorVariable”

  1. $Error « PowerShell и другие скрипты Says:

    […] Learn, PowerShell, Scripting — Xaegr @ 10:36 Кроме описанной в предыдущем посте -ErrorVariable, есть еще одна возможность получить объект […]


Обсуждение закрыто.

%d такие блоггеры, как: