新增非終止錯誤報告到您的 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 不會攔截未處理的例外狀況:
- 如果 Cmdlet 建立新的線程,並在該線程中執行的程式代碼擲回未處理的例外狀況,PowerShell 將不會攔截錯誤並終止進程。
- 如果物件在其解構函式或 Dispose 方法中有導致未處理例外狀況的程式代碼,PowerShell 將不會攔截錯誤並終止進程。
報告非終止錯誤
任何一個輸入處理方法都可以使用 System.Management.Automation.Cmdlet.WriteError 方法,向輸出數據流報告非終止錯誤。
以下是此 Get-Proc Cmdlet 的程式代碼範例,說明從 System.Management.Automation.ProcessRecord 方法的覆寫中呼叫 System.Management.Automation.Cmdlet.WriteError。 在此情況下,如果 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 動作。 其可藉由定義 ErrorAction
和 ErrorVariable
參數來執行此動作。 如果定義 ErrorAction
參數,Cmdlet 會顯示使用者選項 System.Management.Automation.ActionPreference,您也可以藉由設定 $ErrorActionPreference
變數來直接影響動作。
Cmdlet 可以使用 ErrorVariable
參數,將非終止錯誤儲存至變數,但不受 ErrorAction
設定影響。 將加號 (+) 新增至變數名稱前面,即可將失敗附加至現有的錯誤變數。
程式碼範例
如需完整的 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