Escribir un cmdlet de PowerShell para aceptar una ScriptBlock como un parámetro

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

  •  21-09-2019
  •  | 
  •  

Pregunta

El Rename-Item acepta un ScriptBlock (creo ...) como un parámetro para que pueda hacer algo como esto si quiero cambiar el nombre de un grupo de archivos (por ejemplo):

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

Estoy escribiendo un cmdlet para cambiar el nombre de algunos artículos y me gustaría ser capaz de utilizar una sintaxis como esta para el nuevo nombre, pero la forma de declarar el parámetro para aceptar un bloque de script como tal o una cadena simple?

¿Fue útil?

Solución

Si usted está escribiendo un cmdlet basado .NET (C # / VB) a continuación, tenga en cuenta que cualquier parámetro que es obligado tubería apoyará scriptblocks automáticamente. Eso es sólo una característica de PowerShell. Sin embargo, si el parámetro que desea utilizar no está obligado tubería entonces se puede hacer esto:

[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 única cosa que no me gusta de este enfoque es que no se puede utilizar $ _ en el ScriptBlock usted tiene que utilizar $ args [0] en este caso. Tal vez hay una mejor manera de hacer esto y alguien va a meter su cuchara con él.

otoh, Renombrar-Elemento sí especifica el parámetro NuevoNombre como tuberías obligado por nombre de la propiedad. En este caso, usted acaba de hacer el parámetro NuevoNombre sea el tipo que desee (cadena) y dejar que la magia PowerShell hacer ScriptBlock. Lo mejor de todo, en este caso $ _ trabaja en el ScriptBlock por ejemplo:.

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

Otros consejos

Sí. -NewName toma un bloque de script. Prueba esto:

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

  dir *.ps1| Rename-Item -NewName $sb
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top