다음을 통해 공유


Cmdlet에 종료되지 않는 오류 보고 추가

cmdlet은 System.Management.Automation.Cmdlet.WriteError 메서드를 호출하여 종료하지 않는 오류를 보고할 수 있으며 현재 입력 개체 또는 추가 들어오는 파이프라인 개체에서 계속 작동합니다. 이 섹션에서는 입력 처리 메서드에서 종료하지 않는 오류를 보고하는 cmdlet을 만드는 방법을 설명합니다.

종료하지 않는 오류와 종료 오류의 경우 cmdlet은 오류를 식별하는 System.Management.Automation.ErrorRecord 개체를 전달해야 합니다. 각 오류 레코드는 "오류 식별자"라는 고유한 문자열로 식별됩니다. 식별자 외에도 각 오류의 범주는 System.Management.Automation.ErrorCategory 열거형으로 정의된 상수로 지정됩니다. 사용자는 $ErrorView 변수를 "CategoryView"로 설정하여 범주에 따라 오류를 볼 수 있습니다.

오류 레코드에 대한 자세한 내용은 Windows PowerShell 오류 레코드 참조하세요.

Cmdlet 정의

cmdlet 만들기의 첫 번째 단계는 항상 cmdlet의 이름을 지정하고 cmdlet을 구현하는 .NET 클래스를 선언하는 것입니다. 이 cmdlet은 프로세스 정보를 검색하므로 여기서 선택한 동사 이름은 "Get"입니다. (정보를 검색할 수 있는 거의 모든 종류의 cmdlet은 명령줄 입력을 처리할 수 있습니다.) 승인된 cmdlet 동사에 대한 자세한 내용은 Cmdlet 동사 이름참조하세요.

다음은 이 Get-Proc cmdlet에 대한 정의입니다. 이 정의의 세부 정보는 첫 번째 cmdlet 만들기 제공됩니다.

[Cmdlet(VerbsCommon.Get, "proc")]
public class GetProcCommand: Cmdlet
<Cmdlet(VerbsCommon.Get, "Proc")> _
Public Class GetProcCommand
    Inherits Cmdlet

매개 변수 정의

필요한 경우 cmdlet은 입력 처리를 위한 매개 변수를 정의해야 합니다. 이 Get-Proc cmdlet은 입력처리하는 매개 변수 추가에 설명된 대로 Name Command-Line 매개 변수를 정의합니다.

다음은 이 Get-Proc cmdlet의 Name 매개 변수에 대한 매개 변수 선언입니다.

[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

입력 처리 방법 재정의

모든 cmdlet은 System.Management.Automation.Cmdlet 클래스에서 제공하는 입력 처리 방법 중 하나 이상을 재정의해야 합니다. 이러한 메서드는 첫 번째 Cmdlet 만들기설명합니다.

비고

cmdlet은 가능한 한 독립적으로 각 레코드를 처리해야 합니다.

이 Get-Proc cmdlet은 System.Management.Automation.Cmdlet.ProcessRecord 메서드를 재정의하여 사용자 또는 스크립트에서 제공하는 입력에 대한 Name 매개 변수를 처리합니다. 이 메서드는 요청된 각 프로세스 이름 또는 이름이 제공되지 않은 경우 모든 프로세스에 대한 프로세스를 가져옵니다. 이 재정의의 세부 정보는 첫 번째 cmdlet 만들기 제공됩니다.

오류를 보고할 때 기억해야 할 사항

System.Management.Automation.ErrorRecord는 오류를 작성할 때 cmdlet이 전달하는 개체를 핵심에 예외가 필요합니다. 사용할 예외를 결정할 때 .NET 지침을 따릅니다. 기본적으로 오류가 기존 예외와 의미상 동일한 경우 cmdlet은 해당 예외를 사용하거나 파생해야 합니다. 그렇지 않으면 System.Exception 클래스에서 직접 새 예외 또는 예외 계층을 파생해야 합니다.

오류 식별자를 만들 때(ErrorRecord 클래스의 FullyQualifiedErrorId 속성을 통해 액세스됨) 다음 사항에 유의하세요.

  • 정규화된 식별자를 검사할 때 오류의 위치와 오류를 확인할 수 있도록 진단 목적으로 대상으로 하는 문자열을 사용합니다.

  • 올바른 형식의 정규화된 오류 식별자는 다음과 같습니다.

    CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand

이전 예제에서 오류 식별자(첫 번째 토큰)는 오류를 지정하고 나머지 부분은 오류가 발생한 위치를 나타냅니다.

  • 더 복잡한 시나리오의 경우 오류 식별자는 검사 시 구문 분석할 수 있는 점으로 구분된 토큰일 수 있습니다. 이렇게 하면 오류 식별자 및 오류 범주뿐만 아니라 오류 식별자 부분에 대해서도 분기할 수 있습니다.

cmdlet은 다른 코드 경로에 특정 오류 식별자를 할당해야 합니다. 오류 식별자 할당에 대해 다음 정보를 염두에 두세요.

  • 오류 식별자는 cmdlet 수명 주기 내내 일정하게 유지되어야 합니다. cmdlet 버전 간에 오류 식별자의 의미 체계를 변경하지 마세요.
  • 보고되는 오류에 해당하는 오류 식별자에 텍스트를 사용합니다. 공백이나 문장 부호를 사용하지 마세요.
  • cmdlet에서 재현 가능한 오류 식별자만 생성하게 합니다. 예를 들어 프로세스 식별자를 포함하는 식별자를 생성해서는 안 됩니다. 오류 식별자는 동일한 문제가 발생한 다른 사용자가 볼 수 있는 식별자에 해당하는 경우에만 사용자에게 유용합니다.

처리되지 않은 예외는 다음과 같은 조건에서 PowerShell에서 catch되지 않습니다.

  • cmdlet이 새 스레드를 만들고 해당 스레드에서 실행 중인 코드가 처리되지 않은 예외를 throw하는 경우 PowerShell은 오류를 catch하지 않고 프로세스를 종료합니다.
  • 개체에 처리되지 않은 예외를 발생시키는 소멸자 또는 Dispose 메서드의 코드가 있는 경우 PowerShell은 오류를 catch하지 않고 프로세스를 종료합니다.

종료하지 않는 오류 보고

입력 처리 방법 중 하나는 System.Management.Automation.Cmdlet.WriteError 메서드를 사용하여 출력 스트림에 종료하지 않는 오류를 보고할 수 있습니다.

다음은 System.Management.Automation.Cmdlet.ProcessRecord 메서드의 재정의 내에서 system.Management.Automation.Cmdlet.WriteError 호출을 보여 주는 이 Get-Proc cmdlet의 코드 예제입니다. 이 경우 cmdlet이 지정된 프로세스 식별자에 대한 프로세스를 찾을 수 없는 경우 호출이 수행됩니다.

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
  }

종료하지 않는 오류 작성에 대해 기억해야 할 사항

종료가 아닌 오류의 경우 cmdlet은 각 특정 입력 개체에 대한 특정 오류 식별자를 생성해야 합니다.

cmdlet은 종료되지 않는 오류로 인해 생성된 PowerShell 작업을 수정해야 하는 경우가 많습니다. ErrorActionErrorVariable 매개 변수를 정의하여 이 작업을 수행할 수 있습니다. ErrorAction 매개 변수를 정의하는 경우 cmdlet은 System.Management.Automation.ActionPreference 사용자 옵션을 표시하며 $ErrorActionPreference 변수를 설정하여 작업에 직접 영향을 줄 수도 있습니다.

cmdlet은 ErrorAction설정의 영향을 받지 않는 ErrorVariable 매개 변수를 사용하여 종결되지 않는 오류를 변수에 저장할 수 있습니다. 변수 이름 앞에 더하기 기호(+)를 추가하여 기존 오류 변수에 오류를 추가할 수 있습니다.

코드 샘플

전체 C# 샘플 코드는 GetProcessSample04 샘플참조하세요.

개체 형식 및 서식 정의

PowerShell은 .NET 개체를 사용하여 cmdlet 간에 정보를 전달합니다. 따라서 cmdlet은 자체 형식을 정의해야 하거나 cmdlet이 다른 cmdlet에서 제공하는 기존 형식을 확장해야 할 수 있습니다. 새 형식을 정의하거나 기존 형식을 확장하는 방법에 대한 자세한 내용은 개체 형식 확장 및 서식참조하세요.

Cmdlet 빌드

cmdlet을 구현한 후 Windows PowerShell 스냅인을 통해 Windows PowerShell에 등록해야 합니다. cmdlet 등록에 대한 자세한 내용은 Cmdlet, 공급자 및 호스트 애플리케이션등록하는 방법을 참조하세요.

Cmdlet 테스트

cmdlet이 PowerShell에 등록되면 명령줄에서 실행하여 테스트할 수 있습니다. 샘플 Get-Proc cmdlet을 테스트하여 오류를 보고하는지 확인해 보겠습니다.

  • PowerShell을 시작하고 Get-Proc cmdlet을 사용하여 "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
    

또한 참조하십시오