编写PowerShell cmdlet以接受脚本块作为参数

时间:2009-09-03 16:19:07

标签: powershell cmdlet

Rename-Item接受一个scriptblock(我认为...)作为参数,所以如果我想重命名一堆文件(例如),我可以这样做:

Dir *.ps1 | Rename-item -NewName {$_.Name -replace ".ps1" ".txt" }

我正在编写一个cmdlet来重命名一些项目,并且希望能够使用这样的语法作为新名称,但是如何声明参数以接受像这样的脚本块或简单的字符串?

2 个答案:

答案 0 :(得分:4)

如果您正在编写基于.NET的cmdlet(C#/ VB),请记住,管道绑定的任何参数都将自动支持脚本块。这只是PowerShell上的一项功能。但是,如果要使用的参数不是管道绑定,则可以执行以下操作:

[Parameter]
public ScriptBlock NewName { get; set; }

[Parameter(ValueFromPipeline = true)]
public string OldName { get; set; }

protected override void ProcessRecord()
{
    Collection<PSObject> results = NewName.Invoke(this.OldName);
    this.Host.UI.WriteLine("New name is " + results[0]);
}

我唯一不喜欢这种方法的是你不能在脚本块中使用$ _,在这种情况下你必须使用$ args [0]。也许有一种更好的方法可以做到这一点,有人会用它来填补它。

OTOH,Rename-Item确实将NewName参数指定为由属性名称绑定的管道。在这种情况下,您只需将NewName参数设置为您想要的类型(字符串),然后让PowerShell执行scriptblock魔术。最重要的是,在这种情况下,$ _在脚本块中起作用,例如:

[Parameter(ValueFromPipelineByPropertyName = true)]
public string NewName { get; set; }

[Parameter(ValueFromPipeline = true)]
public string OldName { get; set; }

protected override void ProcessRecord()
{
    this.Host.UI.WriteLine("New name is " + this.NewName);
}

答案 1 :(得分:3)

是。 -NewName采用脚本块。试试这个:

Function Do-MyRename {
  param([ScriptBlock]$sb)

  dir *.ps1| Rename-Item -NewName $sb
}