Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

PowerShell removes variables from concatenation

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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?

>Solution :

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
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading