Ошибка при вызове стороннего исполняемого файла из Powershell при использовании IDE
-
21-09-2019 - |
Вопрос
У меня есть сценарий PowerShell, использующий du.exe (Использование диска родом из Sysinternals) для расчета размера каталогов.
Если я побегу du c:\Backup
в консоли он работает как положено, но та же строка кода, запущенная в ISE или PowerGui, дает ожидаемый результат плюс ошибку
+ du <<<< c:\backup
+ CategoryInfo : NotSpecified: (:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Почему это?Как мне избежать этой ошибки?Я попробовал вызвать-выражение, используя &
, но не идти.
Спасибо за помощь.
Решение
Чтобы избежать этого, вы можете перенаправить stderr на ноль, например:
du 2> $null
По сути, хост консоли и ISE (а также удаленное взаимодействие) обрабатывают поток stderr по-разному.На хосте консоли было важно, чтобы PowerShell поддерживал такие приложения, как edit.com, для работы вместе с другими приложениями, которые выводят на экран цветной вывод и ошибки.Если поток ввода-вывода не перенаправляется на хост консоли, PowerShell предоставляет собственному EXE-файлу дескриптор консоли для прямой записи.Это обходит PowerShell, поэтому PowerShell не видит записанных ошибок и не может сообщить об ошибке через $error или путем записи в поток stderr PowerShell.
ISE и удаленному взаимодействию не требуется поддерживать этот сценарий, поэтому они видят ошибки в stderr и впоследствии записывают ошибку и обновляют $error.
Другие советы
Недавно я столкнулся с теми же проблемами, но мне хотелось бы, чтобы вывод stderr направлялся на стандартный вывод.Вы могли бы подумать, что следующее будет работать:
& du 2>&1
Но PowerShell интерпретирует перенаправление и обрабатывает его после завершения выполнения команды «du».Обходной путь, который я нашел, — вызвать его с помощью cmd.exe/c:
& cmd /c 'du 2>&1'
Еще один способ подавить NativeCommandError
выход состоит в том, чтобы преобразовать объекты в трубопроводе, чтобы струны как указано внизу этот ответ:
du c:\Backup 2>&1 | %{ "$_" }
Пытаться:
du 2>&1 | %{ "$_" }
Предыдущее FIX перенаправляет ошибки, но вы можете потерять реальную ошибку, если, например, ваше имя пользователя или пароль неверны или если вы используете встроенную аутентификацию, у вас нет доступа.
Итак, вот способ реализовать обработку ошибок и обойти конкретную ошибку (которая не является ошибкой), вызванную psexec.
try{
psexec command .....
}
catch [System.Management.Automation.RemoteException]{
if ($_.TargetObject -like "Connecting to *" -and $_.CategoryInfo.Category -eq "NotSpecified" -and $_.FullyQualifiedErrorId -eq "NativeCommandError" -and $_.InvocationInfo.MyCommand.Name -like "psexec*.exe"){
$error.Remove[$Error[0]]
}
else{
Throw
}
}
catch{
throw
}