Search code examples
powershellpowershell-remoting

Parameters with double quotes are not properly passed to Scriptblock by ArgumentList


I'm writing generic powershell script to perform deployments on remote machines. I have hit one problem I can not overrun, and this problem is with parameters with double quotes in Scriptblock passed by ArgumentList

I have something like this:

$remoteAddress = "some-pc"
$deploymentCommand = "D:\some path\Command.exe"
$deploymentPackages = @(`"“package - one - external"`", `"“package - two - external"`", `"“package - three - internal"`")

foreach ($deploymentPackage in $deploymentPackages)
{
invoke-command -ComputerName $remoteAddress -ScriptBlock { param ($deployCmd, $deployPackage) &  $deployCmd -package:$deployPackage -action:doit } -ArgumentList   $deploymentCommand,$deploymentPackage
}

I have added double quotes in $deploymentPackages. And still I'm getting my command executed remotly like this (which of course fails):

D:\some path\Command.exe -package:package - one - external -action:doit
D:\some path\Command.exe -package:package - two - external -action:doit
D:\some path\Command.exe -package:package - three - external -action:doit

while proper execution path should be:

D:\some path\Command.exe -package:"package - three - external" -action:doit

without quotes around package - one - external which mess up everythig

How to overrun this problem, because i have tested number of solutions and non of them worked.

Thanks for help in advance!


Solution

  • You could do something like this

    $remoteAddress = "some-pc"
    $deploymentCommand = "D:\some path\Command.exe"
    $deploymentPackages = @('package - one - external', 'package - two - external', 'package - three - internal')
    $remoteScript = {
        param( $deployCmd, $deployPackage )
        & $deployCmd "-package:$deployPackage" -action:doit
    }
    
    foreach ($deploymentPackage in $deploymentPackages)
    {
       invoke-command -ComputerName $remoteAddress -ScriptBlock $remoteScript -ArgumentList $deploymentCommand,$deploymentPackage
    }
    

    This bundles -package:<some string here> into a single argument when passed to your executable, which is the same as doing something like -package:"aaa bbb ccc" in cmd.exe.

    I assume you don't want literal quotes passed to the exe, just for -package:<some string here> to be a single argument regardless of spaces in <some string here>

    If you want literal quotes to be passed to the exe, use the above code with

    & $deployCmd "-package:`"$deployPackage`"" -action:doit