Calling msdeploy.exe from powershell with variables that contain spaces

This topic contains 9 replies, has 3 voices, and was last updated by  Poshoholic 4 years, 3 months ago.

  • Author
    Posts
  • #9175

    MikeCheel
    Participant

    I (and apparently many people on the internet) been struggling with calling msdeploy.exe with variables that contain spaces. Here is an example:

    $src='c:\sandbox\Test Folder\A'
    $dest='c:\sandbox\Test Folder\B'
    $msdeploy=Get-Command 'C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe'
    & $msdeploy -verb:sync -source:contentPath="'$src'" -dest:contentPath="'$dest'"

    I can call it when there are no spaces. I can call it with literal values.

    Can anyone tell me how to accomplish calling msdeploy.exe with variables that contain spaces for the parameters? (Warning: everyone else has gone bald pulling out their hair)

  • #9180

    Don Jones
    Keymaster

    So, the problem is probably in the way PowerShell is parsing stuff before passing it off to Cmd.exe. One option would be to dynamically write out a .BAT file and then call it. That'd help get PSH out of the loop. On PSHv3, you might also try the –% trick. Put that after Msdeploy and PowerShell stops parsing from there. Sadly, that means it stops parsing from there – meaning the variables get treated as literals. Nevermind. But maybe the batch file thing.

    Have you guys looked into PSCX's little echoargs tool, to see what PowerShell is actually spewing to Cmd.exe?

  • #9182

    MikeCheel
    Participant

    I can do it with a batch file. I was wondering if it is possible to do it straight out of powershell. I've used the echoargs tool but still have never been able to get it to work. As much as I like powershell (and I really do) am a little disappointed that so far I have had to resort to use the 'old stuff' (i.e. cmd) to do this.

  • #9210

    Poshoholic
    Participant

    You should be able to make this work using PowerShell. Here's what I would do:

    1. Work out the command if you were to enter everything on one line without variables.
    2. Take your equivalent command with variables and expand it to see if it contains what you actually think it contains.

    For example, I took your above code and did this with it:

    $src=’c:\sandbox\Test Folder\A’
    $dest=’c:\sandbox\Test Folder\B’
    $msdeploy=Get-Command ‘C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe’
    @"
    & $msdeploy -verb:sync -source:contentPath="'$src'" -dest:contentPath="'$dest'"
    "@

    This doesn't invoke anything. Instead, it spits out a string showing me what PowerShell would see if it were to expand the variables. This isn't a perfect test, but it can be quite illuminating.

    Also, when you invoke it when there are spaces, what errors are you getting? Knowing those errors would be helpful in identifying which portion of the command is having issues.

  • #9211

    Poshoholic
    Participant

    Oh, and without seeing the results, since I can see what that command looks like with the variables expanded, my guess would be that you don't want to use single-quotes inside of your double-quotes surrounding $src and $dest.

  • #9218

    MikeCheel
    Participant

    @poshoholic

    I can get it to work if I hard code it with literal values. I've tried all sorts of variations (including your suggestions) and could only get it to work by putting the command in a batch file. I've been trying to figure this out for a while now and posted about it in other places. No one has been able to figure it out.

    To answer your question when I do it without the single quotes I get:

    msdeploy.exe : Error: Unrecognized argument '"-source:"contentPath=c:\sandbox\Test'.
    All arguments must begin with "-".
    At C:\Sandbox\msdeploy.ps1:6 char:1
    + & $msdeploy -verb:sync -source:contentPath="$src" -dest:contentPath="$dest"
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (Error: Unrecogn...begin with "-".:Strin
    g) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

    Error count: 1.

    If I use the single quotes like I originally posted I get:

    msdeploy.exe : Error: Unrecognized argument '"-source:"contentPath='c:\sandbox\Test Folder\A'""'. All arguments must begin with
    "-".
    At C:\Sandbox\msdeploy.ps1:6 char:1
    + & $msdeploy -verb:sync -source:contentPath="'$src'" -dest:contentPath="'$dest'"
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (Error: Unrecogn...begin with "-".:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

    Error count: 1.

  • #9220

    Poshoholic
    Participant

    Ok, have you tried Don's suggestion, using -%?

    For example:

    & $msdeploy -% -verb...

    The -% tells PowerShell to stop processing the remaining arguments like they are PowerShell parameters and instead treat them as simple text arguments for the command.

  • #9223

    Poshoholic
    Participant

    Oh, and I get that you want to use variables, so you can work around that, sort of.

    $command = "& `$msdeploy -% -verb:sync -source:contentPath=""'$src'"" -dest:contentPath=""'$dest'"""
    $sb = $ExecutionContext.InvokeCommand.NewScriptBlock($command)
    & $sb

    By defining the command in a string with variables that you want to expand, and then creating the script block with the -% so that it doesn't parse those string arguments, that may be the trick you were looking for.

  • #9224

    MikeCheel
    Participant

    @poshoholic

    I had to adjust the -% to be –% and I had to remove the single quotes completely because they were being included. And then...it...worked!

    Thanks so much!

    One last question please. What is the tick mark doing right before $msdeploy?

  • #9225

    Poshoholic
    Participant

    Excellent, thanks for letting me know! 🙂

You must be logged in to reply to this topic.