2013-07-04 2 views
7

Мой сниппет что-то вроде этого:Как получить код ошибки при наличии ошибки в powershell?

$msg=Remove-Item -Recurse -Force C:\users\bkp 2>&1 
if ($LASTEXITCODE -eq 1) 
{ 
    "Encountered error during Deleting the Folder. Error Message is $msg. Please check." >> $LogFile 
    exit 
} 

Папка C: \ Пользователи \ БКП не существует. Хотя $ msg дает мне сообщение об ошибке $ LASTEXITCODE все еще 0. Как я могу захватить как флаг?

+0

Вы можете просто проверить переменную $ error. В нем содержится каждая ошибка, встречающаяся в вашей сессии, до некоторой степени, так как у нее есть ограничение на распределение памяти. –

ответ

9

$ LASTEXITCODE предназначен только для программ командной строки, чтобы вернуть их статус. Командлеты, встроенные в PS, такие как Remove-item, возвращают свои ошибки до 3-х способов. Для предупреждений они пишут сообщения (или другие объекты .NET) в «предупреждающий поток». В PSv3 существует простой способ перенаправить этот поток в файл: cmdlet blah blah blah 3>warning.out. Второй - через поток ошибок. Этот поток также может быть перенаправлен ... 2>error.out, или, чаще всего, ошибки пойманы с помощью try/catch или trap или записываются в переменную с параметром -ErrorVariable (см. help about_commonparameters). Третий способ - «выбросить» ошибки. Если не поймать (try/catch или trap), заброшенная ошибка приведет к завершению работы скрипта. Брошенные ошибки обычно являются подклассами класса .NET system.Management.Automation.ErrorRecord. ErrorRecord предоставляет намного больше информации об ошибке, чем код возврата.

Если remove-item завершился с ошибкой из-за ошибки, не найденной в файле, она записывает System.Management.Automation.ItemNotFoundException в поток ошибок. Используя try/catch, вы можете фильтровать эту конкретную ошибку или другие конкретные ошибки из remove-item. Если вы просто вводите команды PS из командной строки, вы можете ввести $error[0]|select-object *, чтобы получить много информации о последней ошибке.


Вы можете сделать это:

try { 
    Remove-Item -Recurse -Force C:\users\bkp 2>&1 
} catch { 
    # oops remove-item failed. Write warning then quit 
    # replace the following with what you want to do 
    write-warning "Remove-item encounter error: $_" 
    return # script failed 
} 
+0

не устанавливает ли какие-либо флаги ошибок? –

+0

Похоже, вы просто хотите знать, работала команда или нет? Однако это не всегда решение «да/нет». Например, вы можете указать remove-item, чтобы удалить 10 файлов, но в итоге он удаляет 8, потому что два файла используются другими программами. Вы считаете успех или неудачу? Я думаю, вы, вероятно, захотите использовать try/catch (см. Справку about_try), и, если возникнут какие-либо ошибки, вы хотите, чтобы поймать ошибку и перейти оттуда. Я отредактирую ответ, чтобы дать пример кода –

+2

'try..catch' не работает, потому что ошибка не завершается. Вы должны добавить '-ErrorAction Stop' в' Remove-Item', чтобы сделать ошибку захватывающей. –

12

Вы можете использовать $?automatic variable для определения результата последней команды. Если вам нужен доступ к фактической ошибке, вы можете использовать автоматическую переменную $Error. Первым элементом массива является последняя ошибка:

Remove-Item -Recurse -Force C:\users\bkp 2>&1 
if(-not $?) 
{ 
    $msg = $Error[0].Exception.Message 
    "Encountered error during Deleting the Folder. Error Message is $msg. Please check." >> $LogFile 
    exit 
} 
+0

Отлично .. Позвольте мне попробовать и вернуться .. –

+1

Я думаю, что было бы лучше добавить '-ErrorAction SilentlyContinue', так что если командлет завершился неудачно, потому что он не завершит и не пропустит если утверждение. и сообщение об ошибке не будет дважды печатать на консоли. – Jackie

+0

@ Jackie Да, если OP хочет самостоятельно обрабатывать все ошибки. Однако из его первоначального вопроса он перенаправляет ошибки в стандартный выходной поток, поэтому я думаю, что он все еще хочет их видеть. –

Смежные вопросы