1

I cannot work out how to pass arguments that contain folders with spaces using msdeploy.exe and PowerShell v4.

Sample Powershell Script

write-warning "WITHOUT SPACE"
$fl1 = "d:\nospace\a.txt"
$fl2 = "d:\nospace\b.txt"

$arg1 = "-source:filePath=`"$fl1`""
$arg2 = "-dest:filePath=`"$fl2`""

msdeploy.exe "-verb:sync",$arg1,$arg2

write-warning "WITH SPACE"
$fl1 = "d:\space space\a.txt"
$fl2 = "d:\space space\b.txt"

$arg1 = "-source:filePath=`"$fl1`""
$arg2 = "-dest:filePath=`"$fl2`""

msdeploy.exe "-verb:sync",$arg1,$arg2

When the folder name has no spaces, it works fine, however when it has a space it fails:

msdeploy.exe : Error: Unrecognized argument '"-source:filePath="d:\space'. All arguments must begin with "-".
At E:\PAWS\Payroll System\PES-Branch-FW\Publish\DeployPackage.ps1:253 char:9
+         msdeploy.exe "-verb:sync",$arg1,$arg2
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (Error: Unrecogn...begin with "-".:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError

Error count: 1.

Manually calling msdeploy.exe using the following command:

msdeploy -verb:sync -source:filePath="d:\space space\a.txt" -dest:filePath="d:\space space\b.txt"

This works fine from Command Prompt but does not work from PowerShell.

I have used this blog as an aid but without any luck: http://trycatchfail.com/blog/post/The-trials-and-tribulations-of-using-MSDeploy-with-PowerShell.aspx

Update

I have looked into some more examples. If you perform a standard copy operation powershell is able to pass the path to cmd.exe (copy).

write-warning "WITHOUT SPACE"
$fl1 = "d:\nospace\a.txt"
$fl2 = "d:\nospace\b.txt"

$args = ('"{0}" "{1}"' -f $fl1, $fl2)
write-host $args
cmd /c copy $args

write-warning "WITH SPACE"
$fl1 = "d:\space space\a.txt"
$fl2 = "d:\space space\b.txt"

$args = ('"{0}" "{1}"' -f $fl1, $fl2)
write-host $args
cmd /c copy $args

Using the same approach to update the msdeploy snippet still fails because of the space.

write-warning "WITHOUT SPACE"
$fl1 = "d:\nospace\a.txt"
$fl2 = "d:\nospace\b.txt"

$arg1 = '-source:filePath="{0}"' -f $fl1
$arg2 = '-dest:filePath="{0}"' -f $fl2

$args = '-verb:sync',$arg1, $arg2
msdeploy.exe $args

write-warning "WITH SPACE"
$fl1 = "d:\space space\a.txt"
$fl2 = "d:\space space\b.txt"

$arg1 = '-source:filePath="{0}"' -f $fl1
$arg2 = '-dest:filePath="{0}"' -f $fl2

$args = '-verb:sync',$arg1, $arg2
msdeploy.exe $args

One Solution

https://stackoverflow.com/a/12813048/1497635

I would like to add that three escape characters is absolutely crazy. There must be a neater solution to the problem.

5
  • Related: stackoverflow.com/questions/3499699/… Those suggestions did not help. Commented Aug 6, 2014 at 6:08
  • Are you sure you need the comas in msdeploy.exe "-verb:sync",$arg1,$arg2 ? Commented Aug 6, 2014 at 6:36
  • It's an [System.Object[]] technically. Can build it using [System.Object[]]$args = "argument 1", "argument 2", "argument 3" Just chose to do it the way above to simplify. It was thrown together quickly to allow someone to re-produce it quickly. This issue may not have anything to do with MSDeploy itself but rather how PowerShell passes arguments to other processes like msdeploy.exe or even cmd.exe Commented Aug 6, 2014 at 22:40
  • The path to MSDEPLOY.EXE needs to be added to Environment Variables for it to work: Path = C:\Program Files\IIS\Microsoft Web Deploy V3 Commented Aug 6, 2014 at 22:58
  • An alternative, and more elegant, solution is offered by using Web Deploy PowerShell Cmdlets. And it also solves problems with output redirection that can be a pain to with Invoke-Expression, Start-Process and the Call/& operator. Commented Jan 9, 2015 at 10:46

4 Answers 4

3

I used the suggestion from the following: How do you call msdeploy from powershell when the parameters have spaces?

To derive a "cleaner" solution.

    $msdeploy = "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe";

    write-warning "WITHOUT SPACE"
    $fl1 = "d:\nospace\a.txt"
    $fl2 = "d:\nospace\b.txt"

    $md = $("`"{0}`" -verb:sync -source:filePath=`"{1}`" -dest:filePath=`"{2}`"" -f $msdeploy, $fl1, $fl2)
    cmd.exe /C "`"$md`""

    write-warning "WITH SPACE"
    $fl1 = "d:\space space\a.txt"
    $fl2 = "d:\space space\b.txt"

    $md = $("`"{0}`" -verb:sync -source:filePath=`"{1}`" -dest:filePath=`"{2}`"" -f $msdeploy, $fl1, $fl2)
    cmd.exe /C "`"$md`""
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! I've spent about a day online looking up a solution and this was the only one that worked.
3

When invoking commands PowerShell does some auto quoting that does not work well with MSDeploy. There are a couple of ways to avoid the auto quoting. One is to use the Start-Process cmdlet where you can specify the exact command line that you want but it can become a bit tedious to get the output of the new process to appear as output of the PowerShell script that you are running.

Another option is to use the --% specifier to turn off PowerShell parsing. However, doing that will not allow you to use variables in the command line because - well, parsing has been turned off. But you can get around this by using the Invoke-Expression cmdlet to first build the command line including the --% and whatever variables you want and then let PowerShell evaluate it:

$fl1 = "D:\space space\a.txt";
$fl2 = "D:\space space\b.txt";
$arguments = "-verb:sync -source:filePath=""$fl1"" -dest:filePath=""$fl2"""
$commandLine = 'msdeploy.exe --% ' + $arguments
Invoke-Expression $commandLine

3 Comments

Did you run your own code? MSDeploy does not care about quotes but if executed from powershell it does not work. Hence why the post.
@civon: You are right that my initial answer was completely wrong. However, I have updated my answer with something that hopefully is more useful now.
Thank you. I confirmed that this script works. I like it as it is a lot easier to read than using that silly escape character. Just need to shift the quotes around $fl1 -source:filePath=""$fl1""
1

I've found that this works:

$arguments=@(
"-verb:sync"
,"-source:metakey=lm/$IISSite,computername=$computer,includeAcls=true"
,"-dest:metakey=lm/w3svc/$DestSite"
,"-enableLink:appPool"
,"-allowUntrusted"
,"-skip:attributes.name=ServerBindings"
,"-skip:attributes.name=SecureBindings"
#,"-whatif"
)


Write-Output "Running MSDeploy with the following arguments"
$arguments
$logfile="Sync_$(get-date -format yyyyMMdd-HHmm).log"
Start-Process -FilePath "$msdeploy\msdeploy.exe" -ArgumentList $arguments -WorkingDirectory $msdeploy -RedirectStandardError "Error.txt" -RedirectStandardOutput $logfile -Wait -NoNewWindow

Comments

1

Found an easy solution. Ref: http://answered.site/all-arguments-must-begin-with--at-cwindowsdtldownloadswebserviceswebservicesidservicepublishedwebsitesidservicedeploymentidservicewsdeployps123/4231580/

$msdeploy = "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe"
$msdeployArgs = @(
"-verb:sync",
"-source:iisApp='Default Web Site/HelloWorld'",
"-verbose",
"-dest:archiveDir='c:\temp1'"
)
Start-Process $msdeploy -NoNewWindow -ArgumentList $msdeployArgs

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.