建立不含參數的 Cmdlet
本節說明如何建立 Cmdlet,以從本機計算機擷取資訊而不使用參數,然後將資訊寫入管線。 此處所述的 Cmdlet 是 Get-Proc Cmdlet,可擷取本機計算機進程的相關信息,然後在命令行上顯示該資訊。
備註
請注意,撰寫 Cmdlet 時,Windows PowerShell® 參考元件會下載到磁碟上(預設為 C:\Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0)。 它們不會安裝在全域程式集緩存 (GAC) 中。
命名 Cmdlet
Cmdlet 名稱是由動詞所組成,表示 Cmdlet 所採取動作,以及指出 Cmdlet 所執行之專案的名詞。 由於此範例 Get-Proc Cmdlet 會擷取進程物件,所以它會使用 System.Management.Automation.VerbsCommon 列舉所定義的動詞 “Get”,以及名詞 “Proc” 來表示 Cmdlet 適用於進程專案。
命名 Cmdlet 時,請勿使用下列任何字元:# 、() {} [] & - /\ $ ;: “ '<> | ? @ ` .
選擇名詞
您應該選擇特定的名詞。 最好使用以縮短版本的產品名稱加上前置詞的單一名詞。 此類型的範例 Cmdlet 名稱為 「Get-SQLServer
」。
選擇動詞
您應該使用一組已核准 Cmdlet 指令動詞名稱中的動詞。 如需已核准 Cmdlet 動詞的詳細資訊,請參閱 Cmdlet 指令動詞名稱。
定義 Cmdlet 類別
選擇 Cmdlet 名稱之後,請定義 .NET 類別以實作 Cmdlet。 以下是此範例 Get-Proc Cmdlet 的類別定義:
[Cmdlet(VerbsCommon.Get, "Proc")]
public class GetProcCommand : Cmdlet
<Cmdlet(VerbsCommon.Get, "Proc")> _
Public Class GetProcCommand
Inherits Cmdlet
請注意,在類別定義之前,System.Management.Automation.CmdletAttribute 屬性,使用 語法 [Cmdlet(verb, noun, ...)]
,將這個類別識別為 Cmdlet。 這是所有 Cmdlet 的唯一必要屬性,它可讓 Windows PowerShell 運行時間正確地呼叫它們。 您可以視需要設定屬性關鍵詞來進一步宣告類別。 請注意,我們範例 GetProcCommand 類別的屬性宣告只會宣告 Get-Proc Cmdlet 的名詞和動詞名稱。
備註
針對所有 Windows PowerShell 屬性類別,您可以設定的關鍵詞會對應至屬性類別的屬性。
命名 Cmdlet 類別時,最好在類別名稱中反映 Cmdlet 名稱。 若要這樣做,請使用 「VerbNounCommand」 格式,並將 「Verb」 和 「Noun」 取代為 Cmdlet 名稱中使用的動詞和名詞。 如上一個類別定義所示,範例 Get-Proc Cmdlet 會定義名為 GetProcCommand 的類別,其衍生自 System.Management.Automation.Cmdlet 基類。
這很重要
如果您想要定義直接存取 Windows PowerShell 運行時間的 Cmdlet,您的 .NET 類別應該衍生自 System.Management.Automation.PSCmdlet 基類。 如需此類別的詳細資訊,請參閱 建立定義參數集的 Cmdlet。
備註
Cmdlet 的類別必須明確標示為 public。 未標示為公用的類別預設為內部,且 Windows PowerShell 運行時間找不到。
Windows PowerShell 會為其 Cmdlet 類別使用 Microsoft.PowerShell.Commands 命名空間。 建議您將 Cmdlet 類別放在 API 命名空間的 Commands 命名空間中,例如,xxx.PS。命令。
覆寫輸入處理方法
System.Management.Automation.Cmdlet 類別提供三個主要輸入處理方法,其中至少一個 Cmdlet 必須覆寫。 如需 Windows PowerShell 如何處理記錄的詳細資訊,請參閱 Windows PowerShell 的運作方式。
針對所有類型的輸入,Windows PowerShell 運行時間會呼叫 System.Management.Automation.Cmdlet.BeginProcessing 啟用處理。 如果您的 Cmdlet 必須執行一些前置處理或設定,則可以覆寫此方法來執行這項作。
備註
Windows PowerShell 會使用「記錄」一詞來描述呼叫 Cmdlet 時所提供的參數值集。
如果您的 Cmdlet 接受管線輸入,則必須覆寫 System.Management.Automation.Cmdlet.ProcessRecord 方法,並選擇性地覆寫 System.Management.Automation.Cmdlet.EndProcessing 方法。 例如,如果 Cmdlet 會使用 system.Management.Automation.Cmdlet.ProcessRecord 收集所有輸入,然後一次在輸入上運作,而不是一個元素,就像 Sort-Object
Cmdlet 一樣,Cmdlet 可能會覆寫這兩種方法。
如果您的 Cmdlet 不接受管線輸入,它應該覆寫 System.Management.Automation.Cmdlet.EndProcessing 方法。 請注意,當 Cmdlet 一次無法在某個元素上運作時,經常使用此方法來取代 System.Management.Automation.Cmdlet.BeginProcessing,就像排序 Cmdlet 的情況一樣。
由於此範例 Get-Proc Cmdlet 必須接收管線輸入,所以它會覆寫 System.Management.Automation.Cmdlet.ProcessRecord 方法,並使用 System.Management.Automation.Cmdlet.BeginProcessing 的默認實作,System.Management.Automation.Cmdlet.EndProcessing。 System.Management.Automation.Cmdlet.ProcessRecord 覆寫會擷取進程,並使用 System.Management.Automation.Cmdlet.WriteObject 方法將它們寫入命令行。
protected override void ProcessRecord()
{
// Get the current processes
Process[] processes = Process.GetProcesses();
// Write the processes to the pipeline making them available
// to the next cmdlet. The second parameter of this call tells
// PowerShell to enumerate the array, and send one process at a
// time to the pipeline.
WriteObject(processes, true);
}
Protected Overrides Sub ProcessRecord()
'/ Get the current processes.
Dim processes As Process()
processes = Process.GetProcesses()
'/ Write the processes to the pipeline making them available
'/ to the next cmdlet. The second parameter of this call tells
'/ PowerShell to enumerate the array, and send one process at a
'/ time to the pipeline.
WriteObject(processes, True)
End Sub 'ProcessRecord
輸入處理時要記住的事項
輸入的預設來源是命令行上使用者所提供的明確物件(例如字串)。 如需詳細資訊,請參閱 建立 Cmdlet 以處理命令列輸入。
輸入處理方法也可以從管線上上游 Cmdlet 的輸出物件接收輸入。 如需詳細資訊,請參閱 建立 Cmdlet 以處理管線輸入。 請注意,您的 Cmdlet 可以從命令行和管線來源的組合接收輸入。
下游 Cmdlet 可能不會傳回很長一段時間,或完全不傳回。 因此,Cmdlet 中的輸入處理方法不應該在呼叫 System.Management.Automation.Cmdlet.WriteObject期間保留鎖定,特別是範圍延伸超過 Cmdlet 實例的鎖定。
這很重要
Cmdlet 絕不應呼叫 system.Console.Writeline* 或其對等專案。
- 您的 Cmdlet 在完成處理時,可能會有物件變數來清除它(例如,如果它在 System.Management.Automation.Cmdlet.BeginProcessing 方法中開啟檔案句柄,並且讓句柄保持開啟,以供 System.Management.Automation.Cmdlet.ProcessRecord使用)。 請務必記住,Windows PowerShell 運行時間不一定會呼叫 System.Management.Automation.Cmdlet.EndProcessing 方法,此方法應該執行物件清除。
例如,System.Management.Automation.Cmdlet.EndProcessing 如果 Cmdlet 在中途取消,或 Cmdlet 的任何部分發生終止錯誤,則可能無法呼叫。 因此,需要物件清除的 Cmdlet 應該實作完整的 System.IDisposable 模式,包括完成項,讓運行時間可以在處理結束時呼叫 System.Management.Automation.Cmdlet.EndProcessing 和 System.IDisposable.Dispose*。
程式碼範例
如需完整的 C# 範例程式代碼,請參閱 GetProcessSample01 範例。
定義物件類型和格式設定
Windows PowerShell 會使用 .NET 物件在 Cmdlet 之間傳遞資訊。 因此,Cmdlet 可能需要定義自己的類型,或 Cmdlet 可能需要擴充另一個 Cmdlet 所提供的現有類型。 如需定義新類型或擴充現有類型的詳細資訊,請參閱 擴充物件類型和格式。
建置 Cmdlet
實作 Cmdlet 之後,您必須透過 Windows PowerShell 嵌入式管理單元向 Windows PowerShell 註冊它。 如需註冊 Cmdlet 的詳細資訊,請參閱 如何註冊 Cmdlet、提供者和主應用程式。
測試 Cmdlet
當您的 Cmdlet 已向 Windows PowerShell 註冊時,您可以在命令行上執行它來測試它。 我們範例 Get-Proc Cmdlet 的程式代碼很小,但它仍然使用 Windows PowerShell 運行時間和現有的 .NET 物件,這足以讓它很有用。 讓我們測試它,以進一步瞭解 Get-Proc 可以做什麼,以及其輸出的使用方式。 如需從命令行使用 Cmdlet 的詳細資訊,請參閱開始使用 Windows PowerShell 。
啟動 Windows PowerShell,並取得電腦上執行的目前進程。
Get-Proc
下列輸出隨即出現。
Handles NPM(K) PM(K) WS(K) VS(M) CPU(s) Id ProcessName ------- ------ ----- ----- ----- ------ -- ---------- 254 7 7664 12048 66 173.75 1200 QCTRAY 32 2 1372 2628 31 0.04 1860 DLG 271 6 1216 3688 33 0.03 3816 lg 27 2 560 1920 24 0.01 1768 TpScrex ...
將變數指派給 Cmdlet 結果,以方便作。
$p=Get-Proc
取得進程數目。
$p.Length
下列輸出隨即出現。
63
擷取特定進程。
$p[6]
下列輸出隨即出現。
Handles NPM(K) PM(K) WS(K) VS(M) CPU(s) Id ProcessName ------- ------ ----- ----- ----- ------ -- ----------- 1033 3 2400 3336 35 0.53 1588 rundll32
取得此程式的開始時間。
$p[6].StartTime
下列輸出隨即出現。
Tuesday, July 26, 2005 9:34:15 AM
$p[6].StartTime.DayOfYear
207
取得處理計數大於 500 的進程,並排序結果。
$p | Where-Object {$_.HandleCount -gt 500 } | Sort-Object HandleCount
下列輸出隨即出現。
Handles NPM(K) PM(K) WS(K) VS(M) CPU(s) Id ProcessName ------- ------ ----- ----- ----- ------ -- ---------- 568 14 2164 4972 39 5.55 824 svchost 716 7 2080 5332 28 25.38 468 csrss 761 21 33060 56608 440 393.56 3300 WINWORD 791 71 7412 4540 59 3.31 492 winlogon ...
使用
Get-Member
Cmdlet 列出每個進程可用的屬性。$p | Get-Member -MemberType Property
TypeName: System.Diagnostics.Process
下列輸出隨即出現。
Name MemberType Definition ---- ---------- ---------- BasePriority Property System.Int32 BasePriority {get;} Container Property System.ComponentModel.IContainer Conta... EnableRaisingEvents Property System.Boolean EnableRaisingEvents {ge... ...