Escrevendo um cmdlet PowerShell para aceitar um scriptblock como um parâmetro
-
21-09-2019 - |
Pergunta
O itens renomeado aceita um scriptblock (eu acho ...) como um parâmetro para que eu possa fazer algo assim, se quiser renomear um monte de arquivos (por exemplo):
Dir *.ps1 | Rename-item -NewName {$_.Name -replace ".ps1" ".txt" }
Estou escrevendo um cmdlet para renomear alguns itens e gostaria de poder usar sintaxe como essa para o novo nome, mas como declarar o parâmetro para aceitar um bloco de script como esta ou uma string simples?
Solução
Se você estiver escrevendo um cmdlet baseado em .NET (C#/VB), lembre -se de que qualquer parâmetro que é o limite do pipeline apoiará os scriptblocks automaticamente. Isso é apenas um recurso no PowerShell. Se, no entanto, o parâmetro que você deseja usar não é encadernado, então você pode fazer isso:
[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]);
}
A única coisa que eu não gosto nessa abordagem é que você não pode usar $ _ no scriptblock que precisa usar $ args [0] neste caso. Talvez haja uma maneira melhor de fazer isso e alguém entrará com isso.
OTOH, renomear-itens especifica o parâmetro newname como pipeline ligado pelo nome da propriedade. Nesse caso, basta fazer com que o parâmetro de nome do novo nome seja o tipo que deseja (string) e deixa o PowerShell fazer a magia do scriptblock. O melhor de tudo é que, neste caso, $ _ funciona no scriptblock, por exemplo:
[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);
}
Outras dicas
Sim. -NewName pega um bloco de script. Experimente isso:
Function Do-MyRename {
param([ScriptBlock]$sb)
dir *.ps1| Rename-Item -NewName $sb
}