创建不具有参数的 Cmdlet

本部分介绍如何创建一个 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 名称后,定义用于实现 cmdlet 的 .NET 类。 下面是此示例 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 的类必须显式标记为公共。 未标记为公共的类将默认为内部类,并且不会由 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 使用术语“record”来描述调用 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 方法。 请注意,此方法经常用于代替 System.Management.Automation.Cmdlet.BeginProcessing 当 cmdlet 一次不能对一个元素进行作时,就像排序 cmdlet 的情况一样。

由于此示例 Get-Proc cmdlet 必须接收管道输入,因此它将替代 System.Management.Automation.Cmdlet.ProcessRecord 方法,并使用 System.Management.Automation.Cmdlet.BeginProcessing 的默认实现,System.Management.Automation.Cmdlet.EndProcessingSystem.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 可能不会长时间返回,或者根本不返回。 因此,在调用 System.Management.Automation.Cmdlet.WriteObject 时,cmdlet 中的输入处理方法不应持有锁,尤其是范围扩展到 cmdlet 实例之外的锁。

重要

Cmdlet 绝不应调用 System.Console.Writeline* 或其等效项。

例如,如果 cmdlet 在中途取消或 cmdlet 的任何部分发生终止错误,则可能不会调用 System.Management.Automation.Cmdlet.EndProcessing。 因此,需要对象清理的 cmdlet 应实现完整的 System.IDisposable 模式,包括终结器,以便运行时可以在处理结束时调用 System.Management.Automation.Cmdlet.EndProcessingSystem.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 入门。

  1. 启动 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
    ...
    
  2. 将变量分配给 cmdlet 结果,以便更轻松地作。

    $p=Get-Proc
    
  3. 获取进程数。

    $p.Length
    

    将显示以下输出。

    63
    
  4. 检索特定进程。

    $p[6]
    

    将显示以下输出。

    Handles  NPM(K)  PM(K)  WS(K)  VS(M)  CPU(s)  Id    ProcessName
    -------  ------  -----  -----  -----  ------  --    -----------
    1033     3       2400   3336   35     0.53    1588  rundll32
    
  5. 获取此过程的开始时间。

    $p[6].StartTime
    

    将显示以下输出。

    Tuesday, July 26, 2005 9:34:15 AM
    
    $p[6].StartTime.DayOfYear
    
    207
    
  6. 获取句柄计数大于 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
    ...
    
  7. 使用 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...
    ...
    

另请参阅

创建 Cmdlet 来处理命令行输入

创建 Cmdlet 来处理管道输入

如何创建 Windows PowerShell Cmdlet

扩展对象类型和格式设置

Windows PowerShell 的工作原理

如何注册 Cmdlet、提供程序和主机应用程序

Windows PowerShell 参考

Cmdlet 示例