Escrevendo um cmdlet PowerShell para aceitar um scriptblock como um parâmetro

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

  •  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?

Foi útil?

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
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top