0

I have script D, C and B :

ScriptD.ps1 ← caller
ScriptC.ps1 ← script path without space
Script B.ps1 ← script path with space

Script B & ScriptC:

Param([int]$Major, [int]$Minor, [String[]]$Output = @())

Write-Host "`n_______________________________________________________________________________________`n"
Write-Host "Script C:`nMajor = $Major ($($Major.GetType()))`nMinor = $Minor ($($Minor.GetType()))`nOutput = $Output (Type: $($Output.GetType()), Length: $($Output.Length))" -ForegroundColor Green

foreach($string in $Output) {
    Write-Host "`t- $string"
}

Then I call ScriptC.ps1, Script B.ps1 from ScriptD.ps1:

$cmd1 = "C:\ScriptTest\ScriptC.ps1 -Major 1 -Minor 2 -Output A,B"
powershell -Command $cmd1 #WORK

$cmd2 = "C:\ScriptTest\Script B.ps1 -Major 1 -Minor 2 -Output A,B"
powershell -Command $cmd2 #DON'T WORK

$cmd2 = "'C:\ScriptTest\Script B.ps1' -Major 1 -Minor 2 -Output A,B" #DON'T WORK
$cmd2 = '"C:\ScriptTest\Script B.ps1" -Major 1 -Minor 2 -Output A,B' #DON'T WORK
$cmd2 = $('"{0}"' -f ("C:\ScriptTest\Script B.ps1")) + " -Major 1 -Minor 2 -Output A,B" #DON'T WORK

If there are spaces in the script path or in a variable the call don't work. Adding single quotes will not solve that problem.

What's wrong?

How could I use the -Command parameter with spaces in path and passed variables?

2
  • 1
    Use Get-Help to read about_operators esp, the & call operator,Invoke-Command and -ArgumentList. Also about_quoting Commented Aug 9, 2019 at 8:25
  • related: stackoverflow.com/a/50023419 Commented Feb 14, 2024 at 21:25

1 Answer 1

3

Don't do what you're doing. There is zero reason to invoke PowerShell scripts from another PowerShell script the way you do.

Change

$cmd1 = "C:\ScriptTest\ScriptC.ps1 -Major 1 -Minor 2 -Output A,B"
powershell -Command $cmd1

$cmd2 = "C:\ScriptTest\Script B.ps1 -Major 1 -Minor 2 -Output A,B"
powershell -Command $cmd2

into

C:\ScriptTest\ScriptC.ps1 -Major 1 -Minor 2 -Output A,B
& "C:\ScriptTest\Script B.ps1" -Major 1 -Minor 2 -Output A,B

and everything will work.

Even if you needed to start the other scripts in a separate process you wouldn't use the approach you chose, but something like this:

$paramsc = '-File', 'C:\ScriptTest\ScriptC.ps1',
           '-Major', 1, '-Minor', 2, '-Output', 'A,B'
Start-Process 'powershell.exe' -ArgumentList $paramsc

$paramsb = '-File', '"C:\ScriptTest\Script B.ps1"',
           '-Major', 1, '-Minor', 2, '-Output', 'A,B'
Start-Process 'powershell.exe' -ArgumentList $paramsb

The ugly nested quotes in the second example are required because the script path contains a space and must thus be in double quotes for the creation of the external process. However, I doubt that you'll be able to pass output variables back to the caller across process boundaries.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your response. My usecase is to pass a script call (ScriptC) as variable from ScriptA to ScriptB. So ScriptB should be able to call ScriptC. Currently I follow the approach with Invoke-Expression $expression where the expression is: $expression = "& $varScript -Major $varMajor -Minor $varMinor -Output $varOutput" ($varScript = "'C:\ScriptTest\Script C.ps1'" and $varOutput = "a,b"). But I get issues when I try to pass variables with spaces. I will check out your suggestion.
@MarTin That is not what your question says. You can certainly do that by passing the script as a string and then invoking that path string via the call operator (&). However, that should be asked as a new question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.