Search code examples
powershellpowershell-corepowershell-7.0

Unable to use the "ForEach-Object -Parallel" in a directory with a name containing "["


Using the ForEach-Object -Parallel cmdlet in a directory with a name containing "[" will return a WildcardPatternException. Remove -Parallel, it will run successfully.

I created a few directories and ran the following commands.
1..5 | ForEach-Object -Parallel {Write-Host $_}
A difference of a return for each ran directory is as follows.

PS D:\[example> 1..5 | ForEach-Object -Parallel {Write-Host $_}

WildcardPatternException will be returned.

PS D:\[]example> 1..5 | ForEach-Object -Parallel {Write-Host $_}
PS D:\[ex]ample> 1..5 | ForEach-Object -Parallel {Write-Host $_}

ItemNotFoundException will be returned.

PS D:\[e]xample> 1..5 | ForEach-Object -Parallel {Write-Host $_}
PS D:\]example> 1..5 | ForEach-Object -Parallel {Write-Host $_}

Ran successfully and 5 values are returned.

Is there a way to resolve this without renaming directories?


Solution

  • As mentioned in the comments, this is a bug.

    ForEach-Object -Parallel works by offloading execution of the scriptblock to multiple background runspaces via something called a TaskPool.

    In order to mimic the callers environment, PowerShell configures the background runspaces to resemble the default runspace, including setting the current provider lotation to whatever the callers is.

    Unfortunately, the internal API for setting the current location defaults to expand wildcards, the equivalent of defaulting to:

    Set-Location -Path 'D:\[]example'
    

    instead of

    Set-Location -LiteralPath 'D:\[]example'
    

    This has now been patched (both for ForEach-Object -Parallel and Start-PSThreadJob), expect both to ship with version 7.1 later this year