Search code examples
powershellsyntaxpipeline

Command in ForEach-Object script block unexpectedly prompts for arguments


I have the following script

$sourceRoot = "C:\Users\skywalker\Desktop\deathStar\server"
$destinationRoot = "C:\Users\skywalker\Desktop\deathStar/server-sandbox"
$dir = get-childitem $sourceRoot  -Exclude .env, web.config   

Write-Output "Copying Folders"
$i=1
$dir| %{
    [int]$percent = $i / $dir.count * 100
    Write-Progress -Activity "Copying ... ($percent %)" -status $_  -PercentComplete $percent -verbose
    copy -Destination $destinationRoot  -Recurse -Force
    $i++

I tried to reference this post, but I ended up getting the following prompt in the powershell console.

Supply values for the following parameters:

Path[0]:


Solution

  • You're using % (ForEach-Object) to process input from the pipeline ($dir) object by object.

    Inside the script block ({ ... }) that operates on the input, you must use the automatic $_ variable to reference the pipeline input object at hand - commands you use inside the script block do not themselves automatically receive that object as their input.

    Therefore, your copy (Copy-Item) command:

    copy -Destination $destinationRoot  -Recurse -Force
    

    lacks a source argument and must be changed to something like:

    $_ | copy -Destination $destinationRoot  -Recurse -Force
    

    Without a source argument (passed to -Path or -LiteralPath) - which is mandatory - Copy-Item prompts for it, which is what you experienced (the default parameter is -Path).

    In the fixed command above, passing $_ via the pipeline implicitly binds to Copy-Item's -LiteralPath parameter.