Rédaction d'une applet de commande PowerShell pour accepter un scriptblock comme paramètre

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

  •  21-09-2019
  •  | 
  •  

Question

La Rename-Item accepte un scriptblock (je pense ...) en tant que paramètre que je peux faire quelque chose comme ça si je veux renommer un groupe de fichiers (par exemple):

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

J'écris une applet de commande pour renommer certains éléments et voudrais pouvoir utiliser cette syntaxe pour le nouveau nom, mais comment déclarer le paramètre d'accepter un bloc de script comme celui-ci ou une chaîne simple?

Était-ce utile?

La solution

Si vous écrivez une applet de commande .NET (C # / VB), alors gardez à l'esprit que tout paramètre qui est lié pipeline soutiendra scriptblocks automatiquement. C'est juste une fonctionnalité sur PowerShell. Si toutefois, le paramètre que vous voulez utiliser n'est pas lié pipeline alors vous pouvez faire ceci:

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

La seule chose que je n'aime pas cette approche est que vous ne pouvez pas utiliser $ _ dans le scriptblock vous devez utiliser args $ [0] dans ce cas. Peut-être il y a une meilleure façon de le faire et quelqu'un sonnera avec elle.

OTOH, Rename-Item ne spécifier le paramètre NewName comme pipeline lié par nom de la propriété. Dans ce cas, vous venez de faire le paramètre NewName soit le type que vous voulez (string) et laissez PowerShell faire la magie de scriptblock. Le meilleur de tous, dans ce cas $ _ fonctionne dans le scriptblock par exemple:.

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

Autres conseils

Oui. -NewName prend un bloc de script. Essayez ceci:

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

  dir *.ps1| Rename-Item -NewName $sb
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top