3

Rename-Item はスクリプトブロック (私が思うに...) をパラメーターとして受け入れるので、一連のファイルの名前を変更したい場合は、次のようにすることができます (たとえば)。

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

いくつかのアイテムの名前を変更するコマンドレットを作成していて、新しい名前にこのような構文を使用できるようにしたいのですが、このようなスクリプト ブロックまたは単純な文字列を受け入れるようにパラメーターを宣言する方法を教えてください。

4

2 に答える 2

4

.NET ベースのコマンドレット (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 にスクリプト ブロック マジックを実行させるだけです。何よりも、この場合 $_ はスクリプトブロックで機能します。

[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);
}
于 2009-09-03T23:25:47.400 に答える
3

はい。-NewName はスクリプト ブロックを受け取ります。これを試して:

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

  dir *.ps1| Rename-Item -NewName $sb
}
于 2009-09-03T17:00:10.963 に答える