In the previous example we showed the special nature of the -NewName parameter in Rename-Item. it accepts a new file name, but also a script block that can be used to bulk-rename many files.

Let’s now take a look at how PowerShell functions can implement such magic parameters! Here is a function that defines two parameters:

function Test-MagicFunc
{
  [CmdletBinding()]
  param
  (

    [Parameter(Mandatory=$true, Position=0, ValueFromPipeline)]
    [string]
    $Par1,

   

    [Parameter(ValueFromPipelineByPropertyName)]
    [string]
    $Par2
  )


  begin 
  {
    Write-Warning "Starting..."
  }

  process
  {
    Write-Warning "Processing Par1=$Par1 and Par2=$Par2"
  }

  end
  {
    Write-Warning "Ending..."
  }
}

You can run it as a classic stand-alone function:

 
PS>  Test-MagicFunc -Par1 100 -Par2 50
WARNING: Starting...
WARNING: Processing  Par1=100 and Par2=50
WARNING: Ending... 
 

You can run it via pipeline input, and submit a static second parameter:

 
PS> 1..4 |  Test-MagicFunc -Par2 99
WARNING: Starting...
WARNING: Processing Par1=1  and Par2=99
WARNING: Processing  Par1=2 and Par2=99
WARNING: Processing  Par1=3 and Par2=99
WARNING: Processing  Par1=4 and Par2=99
WARNING: Ending...  
 

But you can also submit a script block to the second parameter that then refers to the objects that are received from the pipeline:

 
PS> 1..4 |  Test-MagicFunc -Par2 { $_ * $_ }
WARNING: Starting...
WARNING: Processing  Par1=1 and Par2=1
WARNING: Processing  Par1=2 and Par2=4
WARNING: Processing  Par1=3 and Par2=9
WARNING: Processing  Par1=4 and Par2=16
WARNING: Ending... 
 

As it turns out, this magic is very simple: the parameter declaration for -Par2 parameter shows that it can accept pipeline input. It does not matter whether it is input by property name (ValueFromPipelineByPropertyName) or by value (ValueFromPipeline). In either of these cases, when you submit a script block to the parameter, PowerShell treats the script block as interface to the incoming pipeline value: $_ refers to the incoming object, and your script block can use whatever code is necessary to calculate the value that will be bound to the parameter.

Twitter This Tip! ReTweet this Tip!

Anonymous