创建不具有参数的 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 名称后,定义 .NET 类来实现 cmdlet。 下面是此示例 cmdlet 的类Get-Proc定义:

[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 命名空间的命令命名空间中,例如 xxx.PS.Commands。

重写输入处理方法

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收集所有输入,然后像 cmdlet 一样以整体而不是一个元素的方式对输入进行操作,则 cmdlet 可能会重写这两种方法。 Sort-Object

如果 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.BeginProcessingSystem.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 可能长时间不返回,或者完全不返回。 因此,在 调用 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

将 cmdlet 注册到 Windows PowerShell后,可以通过在命令行上运行它来测试它。 示例 cmdlet Get-Proc代码很小,但仍使用 Windows PowerShell 运行时和现有 .NET 对象,这足以使其有用。 让我们测试它,更好地了解Get-Proc功能及其输出的使用方式。 有关从命令行使用 cmdlet 的信息,请参阅入门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 示例