代码之家  ›  专栏  ›  技术社区  ›  marcus.greasly

写入PowerShell cmdlet以接受ScriptBlock作为参数

  •  3
  • marcus.greasly  · 技术社区  · 15 年前

    重命名项接受一个脚本块(我认为是…)作为参数,因此如果我想重命名一组文件(例如):

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

    我正在编写一个Cmdlet来重命名一些项,希望能够对新名称使用类似于此的语法,但是如何声明参数以接受类似于此或简单字符串的脚本块?

    2 回复  |  直到 15 年前
        1
  •  4
  •   Keith Hill    15 年前

    如果要编写基于.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]。也许有更好的方法可以做到这一点,有人会同意的。

    或者,Rename项不将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);
    }
    
        2
  •  3
  •   Doug Finke    15 年前

    对。-newname接受一个脚本块。试试这个:

    Function Do-MyRename {
      param([ScriptBlock]$sb)
    
      dir *.ps1| Rename-Item -NewName $sb
    }
    
    推荐文章