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

问题描述:

Rename-Item接受一个scriptblock(我认为...)作为参数,所以我可以做这样的事情,如果我想重命名一堆文件(例如):编写一个PowerShell cmdlet接受一个脚本块作为参数

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

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

如果你正在编写一个基于.NET的cmdlet的(C#/ VB),那么请记住,这是管道势必将自动支持scriptblocks任何参数。这只是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执行脚本魔术。最重要的是,在这种情况下,$ _作品在脚本块例如为:

[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); 
} 
+0

是的,这就是我想做的事 - 如果重命名,项目设置参数为管道绑定这是配不上我。 – 2009-09-04 10:25:40

+0

如何知道在这种情况下可以使用ScriptBlocks?我认为这会比使用ForEach命令进行封装的时候带来更少的开销? – Josh 2012-05-18 14:22:49

+0

@JoshEinstein我认为这不是开销。运行一个或多个cmdlet开始/处理/结束。 – 2012-05-18 15:04:29

是的。 -NewName需要一个脚本块。试试这个:

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

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