Home > Software design >  PowerShell removes variables from concatenation
PowerShell removes variables from concatenation

Time:06-28

I want to iterate over folders and execute a command per folder, ignoring the already processed ones.

For this I'm trying to concatenate variables to produce a command and then execute this string. But PowerShell (v7.2.5) is removing the variables from concatenation (or replacing them with empty strings). I tried many different syntaxes like $($var1) $($var2) or "$var1 $var2", none of them work. My current approach (it will run with Invoke-Expression -Command instead of echo):

$arguments = "-a -b -c"
$exe = "C:\foo\bar.exe"
$targetdir = "C:\path\"

Get-ChildItem $targetdir -Directory | ForEach-Object -Parallel {If($_.FullName.Contains("processed")){continue}; echo ("{0} -d {1} {2}" -f $($exe),$($_.FullName),$($arguments));} -ThrottleLimit 8 

Expected:

C:\foo\bar.exe -d C:\path\101 -a -b -c
C:\foo\bar.exe -d C:\path\102 -a -b -c
C:\foo\bar.exe -d C:\path\103 -a -b -c

Output:

 -d C:\path\101
 -d C:\path\102
 -d C:\path\103

Why is PowerShell removing paths or arguments from the concatenation and how do I fix this?

CodePudding user response:

As stated in the the ForEach-Object MS Docs:

The ForEach-Object -Parallel parameter set runs script blocks in parallel on separate process threads. The $using: keyword allows passing variable references from the cmdlet invocation thread to each running script block thread.

Do not use continue outside of a loop, switch, or trap:

Using continue inside a pipeline, such as a ForEach-Object script block, not only exits the pipeline, it potentially terminates the entire runspace.

You can use return to emulate the behavior that continue has on a loop:

$arguments = '-a -b -c'
$exe = 'C:\foo\bar.exe'
$targetdir = 'C:\path'

Get-ChildItem $targetdir -Directory | ForEach-Object -Parallel {
    if($_.FullName.Contains('processed')) {
        return
    }
    "{0} -d {1} {2}" -f $using:exe, $_.FullName, $using:arguments
} -ThrottleLimit 8
  • Related