Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Командлеты могут сообщать об ошибках без конца путем вызова метода System.Management.Automation.Cmdlet.WriteError и по-прежнему продолжать работать с текущим входным объектом или на последующих входящих объектах конвейера. В этом разделе объясняется, как создать командлет, который сообщает о неисключающих ошибках из методов обработки входных данных.
Для неустранимых ошибок (а также завершающихся ошибок) командлет должен передать объект System.Management.Automation.ErrorRecord, определяющий ошибку. Каждая запись об ошибке определяется уникальной строкой, называемой идентификатором ошибки. Помимо идентификатора, категория каждой ошибки определяется константами, определенными перечислением System.Management.Automation.ErrorCategory. Пользователь может просматривать ошибки на основе их категории, задав переменную $ErrorView
значение CategoryView.
Дополнительные сведения об ошибках см. в записях об ошибках Windows PowerShell.
Определение командлета
Первым шагом в создании командлета является всегда именование командлета и объявление класса .NET, реализующего командлет. Этот командлет извлекает сведения о процессе, поэтому выбранное здесь имя команды — Get. (Практически любой вид командлета, который может получить информацию, может обрабатывать входные данные командной строки.) Дополнительные сведения о утвержденных командах командлетов см. в имена командлетов.
Ниже приведено определение этого Get-Proc
командлета. Сведения об этом определении приведены в создании первого командлета.
[Cmdlet(VerbsCommon.Get, "proc")]
public class GetProcCommand: Cmdlet
<Cmdlet(VerbsCommon.Get, "Proc")> _
Public Class GetProcCommand
Inherits Cmdlet
Определение параметров
При необходимости командлет должен определить параметры для обработки входных данных. Этот командлет Get-Proc определяет параметр имени, как описано в добавлении параметров, которые Command-Line входных.
Ниже приведено объявление параметров для параметра Name этого командлета Get-Proc.
[Parameter(
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true
)]
[ValidateNotNullOrEmpty]
public string[] Name
{
get { return processNames; }
set { processNames = value; }
}
private string[] processNames;
<Parameter(Position:=0, ValueFromPipeline:=True, _
ValueFromPipelineByPropertyName:=True), ValidateNotNullOrEmpty()> _
Public Property Name() As String()
Get
Return processNames
End Get
Set(ByVal value As String())
processNames = value
End Set
End Property
Переопределение методов обработки входных данных
Все командлеты должны переопределить по крайней мере один из методов обработки входных данных, предоставляемых классом System.Management.Automation.Командлет. Эти методы рассматриваются в создании первого командлета.
Примечание.
Командлет должен обрабатывать каждую запись как можно независимо.
Этот командлет Get-Proc переопределяет метод System.Management.Automation.Cmdlet.ProcessRecord для обработки параметра Name для ввода, предоставленного пользователем или скриптом. Этот метод получает процессы для каждого запрошенного имени процесса или всех процессов, если имя не указано. Сведения об этом переопределении приведены в создании первого командлета.
Действия, которые следует помнить при создании отчетов об ошибках
Объект System.Management.Automation.ErrorRecord, который командлет передает при написании ошибки, требует исключения в его основе. При определении используемого исключения следуйте рекомендациям .NET. В основном, если ошибка семантически совпадает с существующим исключением, командлет должен использовать или производный от этого исключения. В противном случае он должен получить новую иерархию исключений или исключений непосредственно из класса System.Exception.
При создании идентификаторов ошибок (доступ к свойству ПолностьюQualifiedErrorId класса ErrorRecord) следует учитывать следующее.
Используйте строки, предназначенные для диагностических целей, чтобы при проверке полного идентификатора можно определить, какая ошибка и откуда произошла ошибка.
Хорошо сформированный полный идентификатор ошибки может быть следующим образом.
CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand
Обратите внимание, что в предыдущем примере идентификатор ошибки (первый маркер) указывает, что такое ошибка, а оставшаяся часть указывает, откуда произошла ошибка.
- Для более сложных сценариев идентификатор ошибки может быть маркером, разделенным точкой, который можно проанализировать при проверке. Это позволяет слишком ветвить части идентификатора ошибки, а также идентификатор ошибки и категорию ошибок.
Командлет должен назначать определенные идентификаторы ошибок разным путям кода. Имейте в виду следующие сведения о назначении идентификаторов ошибок:
- Идентификатор ошибки должен оставаться постоянным в течение жизненного цикла командлета. Не изменяйте семантику идентификатора ошибки между версиями командлетов.
- Используйте текст для идентификатора ошибки, который ужасно соответствует сообщаемой ошибке. Не используйте пробелы или знаки препинания.
- Создайте командлет только идентификаторы ошибок, которые воспроизводимы. Например, он не должен создавать идентификатор, содержащий идентификатор процесса. Идентификаторы ошибок полезны только в том случае, если они соответствуют идентификаторам, которые видят другие пользователи, испытывают ту же проблему.
Необработанные исключения не перехватываются PowerShell в следующих условиях:
- Если командлет создает новый поток и код, выполняемый в этом потоке, создает необработанное исключение, PowerShell не перехватит ошибку и завершит процесс.
- Если объект содержит код в деструкторе или методах Dispose, вызывающих необработанное исключение, PowerShell не перехватит ошибку и завершит процесс.
Создание отчетов об ошибках без прекращения
Любой из методов обработки входных данных может сообщать об ошибке, не завершающейся выходному потоку, с помощью метода System.Management.Automation.Cmdlet.WriteError.
Ниже приведен пример кода из этого командлета Get-Proc, который иллюстрирует вызов System.Management.Automation.Automation.WriteError из переопределения метода System.Management.Automation.Командлет.ProcessRecord. В этом случае вызов выполняется, если командлет не может найти процесс для указанного идентификатора процесса.
protected override void ProcessRecord()
{
// If no name parameter passed to cmdlet, get all processes.
if (processNames == null)
{
WriteObject(Process.GetProcesses(), true);
}
else
{
// If a name parameter is passed to cmdlet, get and write
// the associated processes.
// Write a non-terminating error for failure to retrieve
// a process.
foreach (string name in processNames)
{
Process[] processes;
try
{
processes = Process.GetProcessesByName(name);
}
catch (InvalidOperationException ex)
{
WriteError(new ErrorRecord(
ex,
"NameNotFound",
ErrorCategory.InvalidOperation,
name));
continue;
}
WriteObject(processes, true);
} // foreach (...
} // else
}
Что следует помнить о написании неустранимых ошибок
Для неустранимой ошибки командлет должен создать определенный идентификатор ошибки для каждого входного объекта.
Командлет часто требуется изменить действие PowerShell, созданное ошибкой, не завершающейся. Это можно сделать, определив параметры ErrorAction
и ErrorVariable
. При определении параметра ErrorAction
командлет предоставляет параметры пользователя System.Management.Automation.ActionPreference, вы также можете напрямую повлиять на действие, задав переменную $ErrorActionPreference
.
Командлет может сохранять неисключаемые ошибки в переменную с помощью параметра ErrorVariable
, который не влияет на параметр ErrorAction
. Ошибки можно добавить в существующую переменную ошибки, добавив знак плюса (+) в передней части имени переменной.
Пример кода
Полный пример кода C# см. в разделе GetProcessSample04 Sample.
Определение типов объектов и форматирования
PowerShell передает сведения между командлетами с помощью объектов .NET. Следовательно, командлету может потребоваться определить собственный тип, или командлету может потребоваться расширить существующий тип, предоставленный другим командлетом. Дополнительные сведения об определении новых типов или расширении существующих типов см. в расширении типов объектов и форматировании.
Создание командлета
После реализации командлета необходимо зарегистрировать его в Windows PowerShell с помощью оснастки Windows PowerShell. Дополнительные сведения о регистрации командлетов см. в разделе Регистрация командлетов, поставщиков и ведущих приложений.
Тестирование командлета
После регистрации командлета в PowerShell его можно протестировать, выполнив его в командной строке. Давайте протестируем пример командлета Get-Proc, чтобы узнать, сообщает ли он об ошибке:
Запустите PowerShell и используйте командлет Get-Proc для получения процессов с именем TEST.
Get-Proc -Name test
Отображаются следующие выходные данные.
Get-Proc : Operation is not valid due to the current state of the object. At line:1 char:9 + Get-Proc <<<< -Name test
См. также
добавление параметров, которые ввода конвейера конвейера
Добавление параметров, которые обрабатывают Command-Line входных
PowerShell