2009-09-03 21 views
3

Rename-Itemはスクリプトブロックを受け入れます(私は思っています...)をパラメータとして受け取りますので、ファイルの名前を変更する場合など):私はいくつかの項目の名前を変更するコマンドレットを書いているし、新しい名前のために、このような構文を使用できるようにしたいと思いScript Blockをパラメータとして受け入れるためのPowerShellコマンドレットの作成

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

が、どのようにこのなどのスクリプトブロックを受け入れるようにパラメータを宣言する単純な文字列ですか?

答えて

4

:これを試してみてください。これは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

はい、それは私がやってみたかったものだ - パイプラインがそれは私には十分だバインドされている名前の変更、項目のパラメータを設定した場合。 –

+0

この文脈でScriptBlocksを使用できることを知らずに、私はこの長い時間をどのように得ましたか?これは、ForEachコマンドでのラッピングと比較してオーバーヘッドが少なくなると仮定します。 – Josh

+0

@JoshEinstein私はそれがより少ないオーバーヘッドだと思うでしょう。 1つ少ないコマンドレットでbegin/process/endを実行します。 –

3

はい。 -NewNameはスクリプトブロックをとります。あなたは、.NETベースのコマンドレット(C#/ VB)を書いている場合は、パイプラインがバインドされている任意のパラメータが自動的にscriptblocksをサポートすることを心に留めておく

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

    dir *.ps1| Rename-Item -NewName $sb 
} 
関連する問題