Adrian Cederberg
Adrian Cederberg

Reputation: 91

Piping in PowerShell: Connot bind argument to parameter <parameter> because it is null

I have been practicing PowerShell by dealing with some of the tasks I could do in the file explorer. I am organizing some files for a python project which I am doing. My goal was to copy all python files in the current directory into the "V0.0_noProgressBar" directory:

ls -Filter "*.py" | copy $_ "V0.0_noProgressBar"

but it fails:

Cannot bind argument to parameter 'Path' because it is null.
At line:1 char:26
+ ls -filter "*.py" | copy $_ "V0.0_noProgressBar"
+                          ~~
+ CategoryInfo          : InvalidData: (:) [Copy-Item], ParameterBindingValidationException 
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,
  Microsoft.PowerShell.Commands.CopyItemCommand

I assume this should be sufficient information to figure this out, let me know if more is needed. I have run into similar issues a number of times, so there must be a fundamental problem with my understanding of the placeholder $_.

Upvotes: 0

Views: 100

Answers (3)

zett42
zett42

Reputation: 27756

This can be simplified to:

Copy-Item *.py V0.0_noProgressBar

To answer original question, why $_ is not working:

$_ is only valid in script contexts, not just anywhere in the pipeline. E. g. you could use it in a script block of ForEach-Object:

Get-ChildItem -filter "*.py" | ForEach-Object { Copy-Item $_ "V0.0_noProgressBar" }

Upvotes: 2

Walter Mitty
Walter Mitty

Reputation: 18940

If you really want to pass a collection of files through a pipeline, you can do this:

ls -Filter *.py | Copy-Item -Destination  "V0.0-NoProgressBar"

Here the Copy-Item cmdlet has no -Path parameter, so it gets the files from the pipeline. See Help Copy-Item -full to see that the -Path parameter can accept pipeline input.

This is not as simple as answers already given, but it does show an alternative to trying to use $_ in a context where it is unavailable.

Upvotes: 1

Steven
Steven

Reputation: 7057

To augment zett42's succinct answer. $_ makes an appearance in several areas of PowerShell. Some cmdlets allow it's use in a script block the output of which is treated as the argument to the parameter. In keeping with the question the *-Item cmdlets can make use of $_.

Get-ChildItem -Filter "*.txt" | Copy-Item -Destination { "C:\"+ $_.Name }

Obviously that's just an example. Perhaps a more useful case is Rename-Item -NewName { ... $_ ... }. -NewName which also works this way.

Other common cmdlets that make use of $_ are Select-Object, Sort-Object, & Group-Object. Overlapping some of these $_ is used by many cmdlets to help define calculated properties. I strongly recommend reading this about topic. Along with the use of $_ calculated properties are extremely useful. I use them with Select-Object everyday!

Upvotes: 1

Related Questions