Запись в поток ошибок в Powershell с использованием Write-Error

Почему не работает оператор PowerShell Write-Error? Мой вывод не похож на примеры в документации:

PS C:\> Write-Error "This is an error"
Write-Error "This is an error" : This is an error
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException

Я ожидал выхода, похожего на Write-Warning:

PS H:\> Write-Warning "This is a warning"
WARNING: This is a warning

Из документации Write-Error и about_preference_variables я думал, что не вижу никаких исключений?

PS H:\> Get-Help About_Preference_Variables

$ErrorActionPreference
----------------------

...

        PS> $erroractionpreference                      
        Continue        # Display the value of the preference.                

        PS> write-error "Hello, World"                  
                                # Generate a non-terminating error.

        write-error "Hello, World" : Hello, World       
                                # The error message is displayed and
                                  execution continues.

        PS> write-error "Hello, World" -ErrorAction:SilentlyContinue
                                # Use the ErrorAction parameter with a 
                                  value of "SilentlyContinue".
        PS>                                             
                                # The error message is not displayed and
                                  execution continues.

Ответ 1

Чтобы получить выход, похожий на предупреждение записи, вы можете сделать это:

$Host.UI.WriteErrorLine("This is an error")

(реквизит для Криса Сирса для этого ответа)

Ответ 2

Почему вы не думаете, что он работает? Имейте в виду, что PowerShell различает неконвертирующие ошибки, подобные описанным выше, и завершающие ошибки, которые вы получаете при выполнении throw 'Access denied.'. Неограничивающие ошибки записываются в stderr и регистрируются в коллекции ошибок $, но они не прекращают обработку script. Эта функция очень удобна, когда вы обрабатываете (например, удаляете или копируете) кучу файлов. Вы хотите знать, какие файлы не могут быть обработаны, но вы не хотите, чтобы вся операция останавливалась в первом файле, который выдает ошибку.

PowerShell также предоставляет вам возможность "конвертировать" ошибки без прерывания в завершающие ошибки, например.

Remove-Item c:\file-doesnt-exist -ErrorAction Stop; "Did I get here"

Обратите внимание, что в этом случае выполнение останавливается и не печатает строку в конце. Попробуйте без -ErrorAction Stop, и вы увидите ошибку, но вы также увидите строку "Я получил здесь".

Если вы хотите управлять информацией Catogory, вы можете использовать параметр -Category следующим образом:

PS> write-error "foo" -Category 'InvalidResult'
write-error "foo" -Category 'InvalidResult' : foo
    + CategoryInfo          : InvalidResult: (:) [Write-Error], WriteErrorExce..
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException

Но WriteErrorException - это механизм (я думаю), с помощью которого этот командлет вызывает ошибку. Существует параметр Exception, но мне не удавалось использовать его.

Ответ 3

Я считаю, что вы видите ожидаемый результат этого командлета. Вы вводите "Доступ запрещен". аргумент, и он выводит это на хост и, скорее всего, на поток ошибок, как это было предусмотрено. Вы можете подтвердить, что он выводит на переменную $Error, и она должна быть заполнена только что вставленной ошибкой.

то есть.

PS C:\> $error.Clear()

PS C:\> Write-Error "access denied"

Write-Error "access denied" : access denied

    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException

PS C:\> $error

Write-Error "access denied" : access denied

    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException

Я могу видеть, где это будет запутанно, хотя, возможно, MSFT должен изменить ошибку примера от чего-то вроде "Отказано в доступе" до "Foobar" для ясности.

Изменить для ответа на следующий вопрос: По умолчанию errorAction для Write-Error является "continue", поэтому, чтобы заставить его вести себя как Write-Warning, вам нужно было бы добавить -ErrorAction SilentlyContinue. Рассмотрим следующий пример:

PS E:\> $error.clear()
PS E:\> Write-Error 'test'
Write-Error 'test' : test
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException

PS E:\> Write-Error 'test2' -ErrorAction silentlycontinue  

PS E:\> $error[1]
Write-Error 'test' : test
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException

PS E:\> $error[0]
Write-Error 'test2' -ErrorAction silentlycontinue : test2
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException