Anytime you have trouble trying to figure out why a parameter doesn't bind correctly in PowerShell, use Trace-Command as follows:
Trace-Command -Name ParameterBinding -expr { copy-item $f foo.cat.bak } -PSHost
In this case, it works for me. This may be a βfeatureβ of PowerShell 2.0, but you can see how it tries to relate several different times before it comes across:
COERCE arg to [System.String] Trying to convert argument value from System.Management.Automation.PSObject to System.String CONVERT arg type to param type using LanguagePrimitives.ConvertTo CONVERT SUCCESSFUL using LanguagePrimitives.ConvertTo: [C:\Users\Keith\foo.cat]
As usual, when the FileInfo objects are piped, they bind the PropertyName to the LiteralPath parameter. I know that you are probably wondering, did not think that System.IO.FileInfo has the LiteralPath property. Heheh, this is not so. These PowerShell tricky people scroll the PSPath alias over the LiteralPath parameter, and PowerShell βadaptsβ each FileInfo object to add several PS * properties, including PSPath. Therefore, if you want to "literally" match the pipelining behavior that you would use:
Copy-Item -LiteralPath $f.PSPath $targetDir -force
Note that in this case you do not need to specify $ targetDir (as a parameter argument).
source share