【问题标题】:PowerShell & MSDeploy - Arguments with SpacesPowerShell & MSDeploy - 带空格的参数
【发布时间】:2014-09-28 23:08:33
【问题描述】:

我不知道如何使用 msdeploy.exe 和 PowerShell v4 传递包含带空格的文件夹的参数。

Powershell 脚本示例

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

当文件夹名称没有空格时,它可以正常工作,但是当它有空格时,它会失败:

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.

使用以下命令手动调用 msdeploy.exe:

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

这在命令提示符下工作正常,但在 PowerShell 中不起作用。

我使用这个博客作为帮助,但没有任何运气:http://trycatchfail.com/blog/post/The-trials-and-tribulations-of-using-MSDeploy-with-PowerShell.aspx

更新

我研究了更多示例。如果您执行标准的复制操作,powershell 能够将路径传递给 cmd.exe(复制)。

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

使用同样的方法更新msdeploy sn -p 还是因为空间问题而失败。

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

一个解决方案

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

我想补充一点,三个转义字符绝对是疯狂的。这个问题必须有一个更简洁的解决方案。

【问题讨论】:

  • 相关:stackoverflow.com/questions/3499699/… 这些建议没有帮助。
  • 您确定需要 msdeploy.exe "-verb:sync",$arg1,$arg2 中的逗号吗?
  • 从技术上讲,它是一个 [System.Object[]]。可以使用 [System.Object[]]$args = "argument 1", "argument 2", "argument 3" 构建它只是选择了上面的方式来简化。它被迅速拼凑起来,以便有人快速重新生产它。这个问题可能与 MSDeploy 本身无关,而是 PowerShell 如何将参数传递给其他进程,如 msdeploy.exe 甚至 cmd.exe
  • 需要将 MSDEPLOY.EXE 的路径添加到环境变量中才能正常工作:Path = C:\Program Files\IIS\Microsoft Web Deploy V3
  • 使用Web Deploy PowerShell Cmdlets 提供了另一种更优雅的解决方案。它还解决了使用 Invoke-Expression、Start-Process 和 Call/& 运算符时可能会遇到的输出重定向问题。

标签: powershell deployment powershell-3.0 msdeploy webdeploy


【解决方案1】:

找到了一个简单的解决方案。参考: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

【讨论】:

    【解决方案2】:

    我发现这是可行的:

    $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
    

    【讨论】:

      【解决方案3】:

      在调用命令时,PowerShell 会执行一些无法与 MSDeploy 配合使用的自动引用。有几种方法可以避免自动报价。一种是使用 Start-Process cmdlet,您可以在其中指定所需的确切命令行,但将新进程的输出显示为您正在运行的 PowerShell 脚本的输出可能会变得有点乏味。

      另一种选择是使用 --% 说明符来关闭 PowerShell 解析。但是,这样做将不允许您在命令行中使用变量,因为 - 解析已被关闭。但是你可以通过使用Invoke-Expression cmdlet 来解决这个问题,首先构建命令行,包括--% 和你想要的任何变量,然后让 PowerShell 评估它:

      $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
      

      【讨论】:

      • 您是否运行了自己的代码? MSDeploy 不关心引号,但如果从 powershell 执行,它就不起作用。因此,为什么要发布这个帖子。
      • @civon:你说得对,我最初的回答是完全错误的。但是,我已经用希望现在更有用的东西更新了我的答案。
      • 谢谢。我确认此脚本有效。我喜欢它,因为它比使用那个愚蠢的转义字符更容易阅读。只需将引号围绕 $fl1 -source:filePath=""$fl1""
      【解决方案4】:

      我使用了以下建议: How do you call msdeploy from powershell when the parameters have spaces?

      推导出一个“更清洁”的解决方案。

          $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`""
      

      【讨论】:

      • 谢谢!我花了大约一天的时间在网上寻找解决方案,这是唯一有效的解决方案。
      猜你喜欢
      • 2011-03-30
      • 1970-01-01
      • 2021-05-03
      • 1970-01-01
      • 1970-01-01
      • 2021-07-16
      • 2017-05-07
      • 1970-01-01
      • 2010-10-10
      相关资源
      最近更新 更多