Schreiben eines Powershell-Cmdlets, um eine Skript als Parameter zu akzeptieren

StackOverflow https://stackoverflow.com/questions/1374451

  •  21-09-2019
  •  | 
  •  

Frage

Das Rename-Item akzeptiert eine Skript (ich glaube, ...) als Parameter, damit ich etwas tun kann, wenn ich eine Reihe von Dateien (zum Beispiel) umbenennen möge:

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

Ich bin ein Cmdlet schreibe einige Elemente umbenannt und möchte in der Lage sein, Syntax für die neuen Namen wie diese zu verwenden, aber, wie die Parameter zu deklarieren einen Skriptblock so oder einen einfachen String zu akzeptieren?

War es hilfreich?

Lösung

Wenn Sie einen .NET-basierten Cmdlets (C # / VB), dann denken Sie daran, zu schreiben, dass alle Parameter, die Pipeline scriptblocks unterstützt automatisch gebunden ist. Das ist nur ein Merkmal auf Powershell. Wenn jedoch der Parameter, den Sie verwenden möchten, nicht-Pipeline gebunden, dann können Sie dies tun:

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

Das einzige, was ich nicht mag diesen Ansatz ist, dass Sie nicht mehr als $ _ in der Skript verwenden, können Sie $ args verwenden [0] in diesem Fall. Vielleicht gibt es einen besseren Weg, dies zu tun, und jemand wird im Einklang steht es.

OTOH, tut Rename-Item den NewName Parameter als Pipeline von Eigenschaftsnamen gebunden angeben. In diesem Fall machen Sie nur die NewName Parameter der Typ sein, das Sie wollen (string) und lassen Sie Powershell die Skript Magie tun. Das Beste von allem, in diesem Fall $ _ arbeitet in dem Skript z.

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

Andere Tipps

Ja. -Newname nimmt einen Skriptblock. Versuchen Sie folgendes:

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

  dir *.ps1| Rename-Item -NewName $sb
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top