在本文中,将探讨如何编写一个自定义的PowerShell Cmdlet。PowerShell是一个强大的命令行工具,它允许用户和开发者执行各种系统管理和自动化任务。通过编写自定义的Cmdlet,可以扩展PowerShell的功能,以满足特定的需求。
编写Cmdlet的第一步是确定Cmdlet将执行什么操作。这个Cmdlet将增加什么价值?微软已经提供了大量的Cmdlet来促进系统管理和维护。随着对PowerShell的使用越来越多,会发现有很多其他事情可以通过PowerShell的管道架构来完成。本文不涉及PowerShell在系统管理或维护之外的用途的细节,这将是另一天的讨论主题。在本文中,将解释编写PowerShell Cmdlet所需的步骤。
第一步是编写一个类,该类将实现Cmdlet的核心。对于这个基础文章和Cmdlet,不会详细说明是否应该从Cmdlet或PSCmdlet派生类。在大多数情况下,将从Cmdlet派生类,除非正在开发一个需要访问PowerShell运行时或需要执行与运行时相关的复杂任务的Cmdlet。选择Cmdlet的名称非常重要。类名由两个部分组成:动词和名词。动词定义了这个Cmdlet将执行的操作,名词定义了动词作用的对象。例如,对于Cmdlet,想在Amazon.com上搜索书籍。因此,类的动词是"Search"或"Get",名词是"Book"。所以创建了一个名为GetBookCommand的类。可能会问为什么不称之为GetBooksCommand。根据微软的命名指南,为了保持名称的一致性,避免在名词上使用复数。
public class GetBookCommand : Cmdlet {...}
如果Cmdlet可以在不使用任何输入参数的情况下执行其操作,那么不需要做任何事情。但是,如果需要输入参数,那么需要在类中为这些参数定义属性。定义属性的最重要部分是命名它们。微软提供了一些命名属性的指南,以便Cmdlet与所有其他Cmdlet保持一致。有关更多详细信息,请参见微软的Cmdlet参数命名指南。
需要决定哪些参数对于Cmdlet的执行是必需的,哪些是可选的。这就是在属性上使用Parameter属性的地方。这个属性类有可以使用的属性,以微调参数的使用。例如,如果想将参数标记为必需的,可以设置属性的Mandatory属性。将通过在Cmdlet中使用这个属性来演示。对于Get-Book Cmdlet的操作,用户绝对必须提供以下四个命令行参数:
因此,在Cmdlet类中为这些值定义了属性,并在它们上面放置了属性以将它们标记为必需的。以下代码片段显示了AssociateTag属性的定义。
[Parameter(Mandatory = true, HelpMessage = "Specify associate tag issued by Amazon.com")]
[ValidateNotNullOrEmpty]
public string AssociateTag
{
get { return _associateTag; }
set { _associateTag = value; }
}
注意在属性上使用Mandatory和HelpMessage属性。同样注意使用ValidationNotNullOrEmpty属性。可以使用验证属性来允许PowerShell运行时验证用户的输入。
可以重写四个方法来执行Cmdlet:BeginProcessing、ProcessRecord、EndProcessing和StopProcessing。大多数Cmdlet实现只需要关注ProcessRecord方法。这是将操纵输入对象并写入输出的地方。但是,如果Cmdlet需要一些预处理或需要一些初始化,可以重写BeforeProcessing方法并在那里做工作。例如,如果正在实现一个需要在采取任何行动之前与数据库建立连接的Cmdlet,可以在BeginProcessing中做到这一点。如果需要在记录处理后做一些清理工作,可以实现EndProcessing方法并在那里做清理工作。例如,如果Cmdlet中打开了数据库连接,总是可以在EndProcessing中实现清理。StopProcessing的实现将非常重要,如果Cmdlet中有一些需要清理的资源。如果出于某种原因,用户决定取消或停止Cmdlet,那么这个方法将给一个清理的机会。否则,将泄漏资源。以下代码片段显示了在BeginProcessing方法上进行覆盖以执行搜索的方式。在实际实现中,放了一个方法来检查搜索数据的目标位置是否可用。如果目标URL关闭,就没有必要继续进行。
protected override void BeginProcessing()
{
base.BeginProcessing();
CreateDataAPI();
ExecuteSearch();
}
PowerShell运行时将调用Cmdlet的ProcessRecord方法,允许将Cmdlet的对象发送到输出。这是可以实现收集需要显示的记录的地方,然后调用WriteObject将它们发送到输出。还有其他方式可以发送到输出。但是,对于本文,将保持实现简单,并调用WriteObject方法,允许PowerShell运行时处理记录的渲染。
protected override void ProcessRecord()
{
base.ProcessRecord();
foreach (Book book in _books)
{
WriteObject(book);
}
}