Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PowerShell: How can I pipeline objects to a parameter that accepts input "ByPropertyName"?

Tags:

powershell

Here is a sample PowerShell script (it doesn't work) that illustrates what I want to do:

$BuildRoot = '_Provided from script parameter_'
$Files = 'a.dll', 'b.dll', 'c.dll'
$BuiltFiles = $Files | Join-Path $BuildRoot

I have a list of filenames, and a directory name, and I want to join them all together, simple. The problem is that this doesn't work because the Join-Path parameter -ChildPath accepts input from the pipeline ByPropertyName, so the following error is reported:

The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.

I can "fix" it by changing the line to the following:

$BuiltFiles = $Files | Select @{ Name = "ChildPath"; Expression = {$_}} | join-path $BuildRoot 

Basically, the select operation is turning the object into a property value. This works, but it introduces a lot of syntactic noise to accomplish something that seems so trivial. If this is the only way to do it, so be it, but I'd like to make this script maintainable for people in the future, and this is a little hard to grok at first glance.

Is there a cleaner way to accomplish what I'm trying to do here?

like image 851
MarkPflug Avatar asked Nov 14 '13 17:11

MarkPflug


People also ask

How do you pass input in PowerShell?

A: You can prompt for user input with PowerShell by using the Read-Host cmdlet. The Read-Host cmdlet reads a line of input from the PowerShell console. The –Prompt parameter enables you to display a string of text. PowerShell will append a colon to the end of the string.

What is the use of $_ in PowerShell?

The “$_” is said to be the pipeline variable in PowerShell. The “$_” variable is an alias to PowerShell's automatic variable named “$PSItem“. It has multiple use cases such as filtering an item or referring to any specific object.


1 Answers

You can accomplish this a little easier like so:

$Files = 'a.dll', 'b.dll', 'c.dll'
$Files | Join-Path $BuildRoot -ChildPath {$_}

Note: you don't want to put {} around the files. That creates a scriptblock in PowerShell which is essentially an anonymous function. Also, when a parameter is pipeline bound you can use the trick of supplying a scriptblock ({}) where $_ is defined in that scriptblock to be the current pipeline object.

like image 165
Keith Hill Avatar answered Nov 15 '22 04:11

Keith Hill