【问题标题】:How to run an EXE file in PowerShell with parameters with spaces and quotes如何在 PowerShell 中使用带空格和引号的参数运行 EXE 文件
【发布时间】:2010-12-13 00:54:00
【问题描述】:

如何在 PowerShell 中运行以下命令?

C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe -verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=数据库;" -dest:dbfullsql="数据源=.\mydestsource;Integrated Security=false;用户ID=sa;密码=sapass!;数据库=mydb;",computername=10.10.10.10,username=administrator,password=adminpass"

【问题讨论】:

  • 如果您的意思是“在 PowerShell 中”(我将其解释为“在现有的 PowerShell 提示符内)”,那么可以轻松地修改以下示例以满足您的需求。请注意,无需单独来自其参数的命令:# Show any available updates to globally installed npm packages using the npm-check-updates tool [string] $cmd = 'ncu -g' Write-Verbose -Message $cmd Invoke-Command -ScriptBlock ([ScriptBlock]::Create($cmd))
  • 我不知道如何使用“mini-markdown”来编辑上面的注释,使每一行代码出现在一个单独的行上,并且编辑原始注释的5分钟时间限制已经过期。如果现在有人知道使用“mini-Markdown”来解决问题,我会以更易读的形式重新发布。第一行应该如下: # 使用 npm-check-updates 工具显示全局安装的 npm 包的任何可用更新
  • 我从来不知道 cmets 能够允许不同的行。我认为,对于 cmets 中的链接,降价功能仅限于 backticks 和 ()[]。

标签: powershell parameters quotes exe spaces


【解决方案1】:

当 PowerShell 看到以字符串开头的命令时,它只会评估该字符串,也就是说,它通常会将其回显到屏幕上,例如:

PS> "Hello World"
Hello World

如果您希望 PowerShell 将字符串解释为命令名称,请使用调用运算符 (&),如下所示:

PS> & 'C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe'

之后,您可能只需要引用包含空格和/或引号字符的参数/参数对。当您使用复杂的命令行参数调用这样的 EXE 文件时,拥有一个工具通常会非常有帮助,该工具将向您展示 PowerShell 如何将参数发送到 EXE 文件。 PowerShell Community Extensions 有这样的工具。它被称为回声参数。您只需将 EXE 文件替换为 echoargs - 保留所有参数,它会显示 EXE 文件将如何接收参数,例如:

PS> echoargs -verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass

Arg 0 is <-verb:sync>
Arg 1 is <-source:dbfullsql=Data>
Arg 2 is <Source=mysource;Integrated>
Arg 3 is <Security=false;User>
Arg 4 is <ID=sa;Pwd=sapass!;Database=mydb;>
Arg 5 is <-dest:dbfullsql=Data>
Arg 6 is <Source=.\mydestsource;Integrated>
Arg 7 is <Security=false;User>
Arg 8 is <ID=sa;Pwd=sapass!;Database=mydb; computername=10.10.10.10 username=administrator password=adminpass>

您可以使用 echoargs 进行试验,直到正确为止,例如:

PS> echoargs -verb:sync "-source:dbfullsql=Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;"
Arg 0 is <-verb:sync>
Arg 1 is <-source:dbfullsql=Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;>

原来我在维护连接字符串周围的双引号之前太努力了。显然这不是必需的,因为即使是 cmd.exe 也会删除它们。

顺便说一句,向 PowerShell 团队致敬。它们非常有助于向我展示单引号和双引号的特定咒语以获得所需的结果 - 如果您需要保留内部双引号。 :-) 他们也意识到这是一个痛苦的领域,但他们受到受特定问题影响的人数的驱动。如果这对您来说是一个痛苦的领域,那么请投票给PowerShell bug submission

有关 PowerShell 如何解析的更多信息,请查看我的 Effective PowerShell blog series - 特别是 item 10 - "Understanding PowerShell Parsing Modes"

2012 年 4 月 4 日更新:这种情况在 PowerShell V3 中变得更容易处理。看到这个blog post for details

【讨论】:

  • 如果用作第二个示例,我会收到此错误:错误:无法识别的参数 '"-source:dbfullsql="""Data'。所有参数必须以“-”开头。
  • 对不起,我不明白。我看到,目前有 6 人对答案投了赞成票,所以我遗漏了一些明显的东西,但实际答案是什么?在 PowerShell 中是否有关于带空格的参数的特殊规则,或者您只是建议使用 EchoArgs 来帮助逐个案例?
  • 引用参数通常就足够了,但并非总是如此。在它不起作用的情况下,使用 echoargs 可以指示 PowerShell 在将参数传递到 EXE 之前如何解释它们。
  • 您知道我将如何在 .bat 文件中执行此操作吗?我直接在控制台中尝试&amp; 'C:\Program Files\Sublime Text 3\sublime_text.exe' 并且它正在工作,但是在批处理文件中我收到一条错误消息,提示“此时 & 是意外的。”
  • 没关系。找到它:START C:\"Program Files"\"Sublime Text 3"\sublime_text.exe
【解决方案2】:

只需在 .exe 名称前添加 & 运算符即可。 下面是在静默模式下安装 SQL Server Express 的命令:

$fileExe = "T:\SQLEXPRADV_x64_ENU.exe"
$CONFIGURATIONFILE = "T:\ConfSetupSql2008Express.ini"

& $fileExe  /CONFIGURATIONFILE=$CONFIGURATIONFILE

【讨论】:

    【解决方案3】:

    我在命令和参数中都有空格,这对我有用:

    $Command = "E:\X64\Xendesktop Setup\XenDesktopServerSetup.exe"
    $Parms = "/COMPONENTS CONTROLLER,DESKTOPSTUDIO,DESKTOPDIRECTOR,LICENSESERVER,STOREFRONT /PASSIVE /NOREBOOT /CONFIGURE_FIREWALL /NOSQL"
    
    $Prms = $Parms.Split(" ")
    & "$Command" $Prms
    

    这与 Akira 的答案基本相同,但如果您动态构建命令参数并将它们放入变量中,则此方法有效。

    【讨论】:

    • 恕我直言,这是最好的!没有 base64,没有奇怪的 --% 切换替换的语法,正常的 powershell 替换规则,没有混淆,非常易读。
    • 这不起作用。如果你的参数里面有路径名,路径名会分成多个参数。
    • 不错的答案。但是,它可以与参数中的引号一起使用吗?
    • 请试一试,在其他一切都有效之后。并且还使用 Powershell 扩展EchoArgs
    • .Split(" ") 是这个答案的关键部分,它对我有用
    【解决方案4】:

    您可以使用很多方法来做到这一点。

    还有其他方法,例如使用调用运算符 (&)、Invoke-Expression cmdlet 等。但它们被认为是不安全的。 Microsoft 建议使用 Start-Process

    方法一

    一个简单的例子

    Start-Process -NoNewWindow -FilePath "C:\wamp64\bin\mysql\mysql5.7.19\bin\mysql" -ArgumentList "-u root","-proot","-h localhost"
    

    你的情况

    Start-Process -NoNewWindow -FilePath "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -ArgumentList "-verb:sync","-source:dbfullsql=`"Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`"","-dest:dbfullsql=`"Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`"","computername=10.10.10.10","username=administrator","password=adminpass"
    

    在此方法中,您使用逗号分隔 ArgumentList 中的每个参数。

    方法二

    简单示例

    Start-Process -NoNewWindow -FilePath "C:\wamp64\bin\mysql\mysql5.7.19\bin\mysql" -ArgumentList "-u root -proot -h localhost"
    

    你的情况

    Start-Process -NoNewWindow -FilePath "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -ArgumentList "-verb:sync -source:dbfullsql=`"Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`" -dest:dbfullsql=`"Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`",computername=10.10.10.10,username=administrator,password=adminpass"
    

    此方法更简单,因为它允许一次性输入参数。

    请注意,在 powershell 中,要在字符串中表示 引号 ( " ),您应该插入 重音符号 ( ` )(这是 Tab 键上方的键在美式键盘中)。

    -NoNewWindow 参数用于在当前控制台窗口中显示新进程。默认情况下,Windows PowerShell 会打开一个新窗口。

    参考:Powershell/Scripting/Start-Process

    【讨论】:

    • 简单总是赢!谢谢。
    • 感谢转义引号的最后说明!
    【解决方案5】:

    这对我有用:

    & 'D:\Server\PSTools\PsExec.exe' @('\\1.1.1.1', '-accepteula', '-d', '-i', $id, '-h', '-u', 'domain\user', '-p', 'password', '-w', 'C:\path\to\the\app', 'java', '-jar', 'app.jar')
    

    只需将路径或连接字符串放在一个数组项中,然后将其他内容分别拆分为一个数组项。

    这里还有很多其他选项:https://social.technet.microsoft.com/wiki/contents/articles/7703.powershell-running-executables.aspx

    微软应该让这种方式更简单,并与命令提示符语法兼容。

    【讨论】:

    • Array 绝对是最好的选择 - 这对我来说非常有用。除了我传递了一个数组变量,因为我的参数是动态的。谢谢。
    • 恕我直言最佳解决方案
    【解决方案6】:

    查看此页面: https://slai.github.io/posts/powershell-and-external-commands-done-right/

    使用 vshadow 作为外部可执行文件的总结:

    $exe = "H:\backup\scripts\vshadow.exe"
    &$exe -p -script=H:\backup\scripts\vss.cmd E: M: P:
    

    【讨论】:

      【解决方案7】:

      如果有人想知道如何运行一个可执行文件:

      ..... > .\file.exe

      ......> full\path\to\file.exe

      【讨论】:

      • 这应该是该问题的答案,当我们使用“从 PowerShell 启动 EXE”关键字时,我们正在寻找它。谢谢!
      • 带参数运行怎么样?
      • @SereneWizard 好吧,将它们添加到 .exe 之后,中间有一个空格。示例:.\file.exe param1 param2 param3
      • 只要命令名称中有空格,就会失败。然后你必须将命令用引号括起来。然后它会被 Powershell 认为只是一个字符串,并且只是输出,而不是启动的命令,这让我们回到了 OP 的问题。
      • 这一个应该被认为是正确的答案。
      【解决方案8】:

      你可以使用:

      Start-Process -FilePath "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -ArgumentList "-verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass"
      

      这里要注意的关键是,根据帮助指南,FilePath 必须位于位置 0。要调用命令行开关的帮助指南,只需输入 Get-Help &lt;Commandlet-name&gt; -Detailed 。在这种情况下,它是Get-Help Start-Process -Detailed

      【讨论】:

        【解决方案9】:

        我能够使用以下方法使我的类似命令正常工作:

        msdeploy.exe -verb=sync "-source=dbFullSql=Server=THESERVER;Database=myDB;UID=sa;Pwd=saPwd" -dest=dbFullSql=c:\temp\test.sql
        

        对于你的命令(现在不是很有帮助),事情看起来像这样:

        msdeploy.exe -verb=sync "-source=dbfullsql=Server=mysource;Trusted_Connection=false;UID=sa;Pwd=sapass!;Database=mydb;" "-dest=dbfullsql=Server=mydestsource;Trusted_Connection=false;UID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass
        

        重点是:

        • 在源参数周围使用引号,并删除连接字符串周围的嵌入引号
        • 在构建不包含空格的 SQL 连接字符串时使用替代键名。例如,使用“UID”而不是“User Id”、“Server”而不是“Data Source”、“Trusted_Connection”而不是“Integrated Security”等等。只有从连接字符串中删除所有空格后,我才能让它工作。

        我没有尝试在命令行末尾添加“计算机名”部分,但希望这些信息能帮助其他正在阅读本文的人更接近他们想要的结果。

        【讨论】:

        • 我尝试了所有其他答案,但这是唯一对我有用的答案!感谢您提供此替代路径。
        • 只要命令名称中有空格,就会失败。然后你必须将命令用引号括起来。然后它会被 Powershell 认为只是一个字符串,并且只是输出,而不是启动的命令,这让我们回到了 OP 的问题。
        【解决方案10】:

        PowerShell V3 中的新转义字符串,引用自 New V3 Language Features

        从 Cmd.exe 更轻松地重用命令行

        网络上到处都是为 Cmd.exe 编写的命令行。这些命令行在 PowerShell 中经常工作,但是当它们包含某些字符时,例如分号 (;)、美元符号 ($) 或花括号,您必须进行一些更改,可能会添加一些引号。这似乎是许多轻微头痛的根源。

        为了帮助解决这种情况,我们添加了一种“逃避”命令行解析的新方法。如果您使用魔术参数 --%,我们会停止对命令行的正常解析并切换到更简单的东西。我们不匹配引号。我们不止于分号。我们不扩展 PowerShell 变量。如果您使用 Cmd.exe 语法(例如 %TEMP%),我们会扩展环境变量。除此之外,直到行尾的参数(或管道,如果您是管道)按原样传递。这是一个例子:

        PS> echoargs.exe --% %USERNAME%,this=$something{weird}
        Arg 0 is <jason,this=$something{weird}>
        

        【讨论】:

          【解决方案11】:

          我尝试了所有建议,但仍然无法使用包含空格的参数运行 msiexec.exe。所以我的解决方案最终使用System.Diagnostics.ProcessStartInfo

          # can have spaces here, no problems
          $settings = @{
            CONNECTION_STRING = "... ..."
            ENTITY_CONTEXT = "... ..."
            URL = "..."
          }
          
          $settingsJoined = ($settings.Keys | % { "$_=""$($settings[$_])""" }) -join " "
          $pinfo = New-Object System.Diagnostics.ProcessStartInfo
          $pinfo.WorkingDirectory = $ScriptDirectory
          $pinfo.FileName = "msiexec.exe"
          $pinfo.RedirectStandardError = $true
          $pinfo.RedirectStandardOutput = $true
          $pinfo.UseShellExecute = $false
          $pinfo.Arguments = "/l* install.log /i installer.msi $settingsJoined"
          $p = New-Object System.Diagnostics.Process
          $p.StartInfo = $pinfo
          $p.Start() | Out-Null
          $p.WaitForExit()
          $stdout = $p.StandardOutput.ReadToEnd()
          

          【讨论】:

            【解决方案12】:

            我使用这种简单、干净、有效的方法。

            我将参数放在一个数组中,每行 1 个。这种方式很容易阅读和编辑。 然后我使用一个简单的技巧,将双引号内的所有参数传递给具有 1 个单参数的函数。这会将它们(包括数组)扁平化为单个字符串,然后我使用 PS 的“Invoke-Expression”执行该字符串。该指令专门用于将字符串转换为可运行命令。 效果很好:

            # function with one argument will flatten 
            # all passed-in entries into 1 single string line
            Function Execute($command) {
                # execute:
                Invoke-Expression $command;
                # if you have trouble try:
                # Invoke-Expression "& $command";
                # or if you need also output to a variable
                # Invoke-Expression $command | Tee-Object -Variable cmdOutput;
            }
            
            #  ... your main code here ...
            
            # The name of your executable app
            $app = 'my_app.exe';
            # List of arguments:
            # Notice the type of quotes - important !
            # Those in single quotes are normal strings, like 'Peter'
            $args = 'arg1',
                    'arg2',
                    $some_variable,
                    'arg4',
                    "arg5='with quotes'",
                    'arg6',
                    "arg7 \ with \ $other_variable",
                    'etc...';
                
            # pass all arguments inside double quotes
            Execute "$app $args";
              
            

            【讨论】:

              【解决方案13】:

              您可以在 powershell 中以不同的方式运行 exe 文件。例如,如果你想运行 unrar.exe 并提取一个 .rar 文件,你可以简单地在 powershell 中这样写:

              $extract_path = "C:\Program Files\Containing folder";
              $rar_to_extract = "C:\Path_to_arch\file.rar"; #(or.exe if its a big file)  
              C:\Path_here\Unrar.exe x -o+ -c- $rar_to_extract $extract_path;
              

              但有时,这不起作用,因此您必须使用 & 参数,如上所示: 例如,使用 vboxmanage.exe(管理 virtualbox 虚拟机的工具),您必须像这样在字符串之外调用参数,不带引号:

              > $vmname = "misae_unrtes_1234123"; #(name too long, we want to change this)
              > & 'C:\Program Files\Oracle\VirtualBox\VBoxManage.exe' modifyvm $vmname --name UBUNTU;
              

              如果您只想将 winrar 归档文件调用为 .exe 文件,您还可以使用 invoke-command cmdlet 和 Silent 参数 /S 将其解压缩(它会将自身解压缩到与之前所在位置相同的文件夹中压缩)。

              > Invoke-Command -ScriptBlock { C:\Your-path\archivefile.exe /S };
              

              所以有几种方法可以在 powershell 中运行带参数的 .exe 文件。

              有时,必须找到一种解决方法才能使其正常工作,这可能需要进一步的努力和痛苦:) 取决于 .exe 的编译方式或创建者的方式。

              【讨论】:

                【解决方案14】:

                Cmd 可以处理运行引用的 exe,但 Powershell 不能。我只是要处理运行 exe 本身,因为我没有它。如果您确实需要将双引号发送到外部命令的参数,那是另一个已在其他地方讨论过的问题。

                1) 将 exe 文件夹添加到您的路径中,可能在您的 $profile 中

                $env:path += ';C:\Program Files\IIS\Microsoft Web Deploy\'
                msdeploy
                

                2) 反引号空格:

                C:\Program` Files\IIS\Microsoft` Web` Deploy\msdeploy.exe
                

                【讨论】:

                  【解决方案15】:

                  这对我有用:

                  PowerShell.exe -Command "& ""C:\Some Script\Path With Spaces.ps1"""
                  

                  关键似乎是整个命令用外引号括起来,“&”和号用于指定正在执行的另一个子命令文件,然后最后在路径/文件周围转义(双双)引号首先要执行的名称中带有空格。

                  这也是解决 MS 连接问题的唯一解决方法,即 -File 不回传非零返回代码,而 -Command 是唯一的替代方法。但到目前为止,人们认为 -Command 的一个限制是它不支持空格。我也更新了该反馈项。

                  http://connect.microsoft.com/PowerShell/feedback/details/750653/powershell-exe-doesn-t-return-correct-exit-codes-when-using-the-file-option

                  【讨论】:

                  • 这和ops问题无关,他在powershell的帖子中专门询问了如何运行long命令。不是如何在文件路径中运行带有空格的 powershell 脚本。
                  • 阅读问题的标题,空格不是问题的长度。这是对此类问题的一个有效答案,因此值得分享。您是否有同样的问题并实际尝试过?如果您想改进它,请提交包含问题中实际命令的编辑,我会接受。
                  【解决方案16】:

                  另一种答案是使用Base64 编码的命令开关:

                  powershell -EncodedCommand "QwA6AFwAUAByAG8AZwByAGEAbQAgAEYAaQBsAGUAcwBcAEkASQBTAFwATQBpAGMAcgBvAHMAbwBmAHQAIABXAGUAYgAgAEQAZQBwAGwAbwB5AFwAbQBzAGQAZQBwAGwAbwB5AC4AZQB4AGUAIAAtAHYAZQByAGIAOgBzAHkAbgBjACAALQBzAG8AdQByAGMAZQA6AGQAYgBmAHUAbABsAHMAcQBsAD0AIgBEAGEAdABhACAAUwBvAHUAcgBjAGUAPQBtAHkAcwBvAHUAcgBjAGUAOwBJAG4AdABlAGcAcgBhAHQAZQBkACAAUwBlAGMAdQByAGkAdAB5AD0AZgBhAGwAcwBlADsAVQBzAGUAcgAgAEkARAA9AHMAYQA7AFAAdwBkAD0AcwBhAHAAYQBzAHMAIQA7AEQAYQB0AGEAYgBhAHMAZQA9AG0AeQBkAGIAOwAiACAALQBkAGUAcwB0ADoAZABiAGYAdQBsAGwAcwBxAGwAPQAiAEQAYQB0AGEAIABTAG8AdQByAGMAZQA9AC4AXABtAHkAZABlAHMAdABzAG8AdQByAGMAZQA7AEkAbgB0AGUAZwByAGEAdABlAGQAIABTAGUAYwB1AHIAaQB0AHkAPQBmAGEAbABzAGUAOwBVAHMAZQByACAASQBEAD0AcwBhADsAUAB3AGQAPQBzAGEAcABhAHMAcwAhADsARABhAHQAYQBiAGEAcwBlAD0AbQB5AGQAYgA7ACIALABjAG8AbQBwAHUAdABlAHIAbgBhAG0AZQA9ADEAMAAuADEAMAAuADEAMAAuADEAMAAsAHUAcwBlAHIAbgBhAG0AZQA9AGEAZABtAGkAbgBpAHMAdAByAGEAdABvAHIALABwAGEAcwBzAHcAbwByAGQAPQBhAGQAbQBpAG4AcABhAHMAcwAiAA=="
                  

                  解码后,您会看到它是 OP 的原始 sn-p,保留了所有参数和双引号。

                  powershell.exe -EncodedCommand
                  
                  Accepts a base-64-encoded string version of a command. Use this parameter
                  to submit commands to Windows PowerShell that require complex quotation
                  marks or curly braces.
                  

                  原来的命令:

                   C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe -verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass"
                  

                  Base64编码后变成这样:

                  QwA6AFwAUAByAG8AZwByAGEAbQAgAEYAaQBsAGUAcwBcAEkASQBTAFwATQBpAGMAcgBvAHMAbwBmAHQAIABXAGUAYgAgAEQAZQBwAGwAbwB5AFwAbQBzAGQAZQBwAGwAbwB5AC4AZQB4AGUAIAAtAHYAZQByAGIAOgBzAHkAbgBjACAALQBzAG8AdQByAGMAZQA6AGQAYgBmAHUAbABsAHMAcQBsAD0AIgBEAGEAdABhACAAUwBvAHUAcgBjAGUAPQBtAHkAcwBvAHUAcgBjAGUAOwBJAG4AdABlAGcAcgBhAHQAZQBkACAAUwBlAGMAdQByAGkAdAB5AD0AZgBhAGwAcwBlADsAVQBzAGUAcgAgAEkARAA9AHMAYQA7AFAAdwBkAD0AcwBhAHAAYQBzAHMAIQA7AEQAYQB0AGEAYgBhAHMAZQA9AG0AeQBkAGIAOwAiACAALQBkAGUAcwB0ADoAZABiAGYAdQBsAGwAcwBxAGwAPQAiAEQAYQB0AGEAIABTAG8AdQByAGMAZQA9AC4AXABtAHkAZABlAHMAdABzAG8AdQByAGMAZQA7AEkAbgB0AGUAZwByAGEAdABlAGQAIABTAGUAYwB1AHIAaQB0AHkAPQBmAGEAbABzAGUAOwBVAHMAZQByACAASQBEAD0AcwBhADsAUAB3AGQAPQBzAGEAcABhAHMAcwAhADsARABhAHQAYQBiAGEAcwBlAD0AbQB5AGQAYgA7ACIALABjAG8AbQBwAHUAdABlAHIAbgBhAG0AZQA9ADEAMAAuADEAMAAuADEAMAAuADEAMAAsAHUAcwBlAHIAbgBhAG0AZQA9AGEAZABtAGkAbgBpAHMAdAByAGEAdABvAHIALABwAGEAcwBzAHcAbwByAGQAPQBhAGQAbQBpAG4AcABhAHMAcwAiAA==
                  

                  这是在家复制的方法:

                  $command = 'C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe -verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass"'
                  $bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
                  $encodedCommand = [Convert]::ToBase64String($bytes)
                  $encodedCommand
                  
                  #  The clip below copies the base64 string to your clipboard for right click and paste.
                  $encodedCommand | Clip
                  

                  【讨论】:

                    【解决方案17】:

                    对于可执行文件名称,可以使用 new-alias cmdlet 来避免处理空格或需要将可执行文件添加到 $PATH 环境。

                    PS> new-alias msdeploy "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe"
                    PS> msdeploy ...
                    

                    要列出或修改 PS 别名,另请参阅

                    PS> get-alias
                    PS> set-alias
                    

                    来自Jeffery Hicks Aarticle

                    其他答案解决了争论。

                    【讨论】:

                      【解决方案18】:

                      以下代码在我的笔记本电脑上完美运行:

                      & $msdeploy `
                      -source:package="$publishFile" `
                      -dest:auto,computerName="$server",includeAcls="False",UserName="$username",Password="$password",AuthType="$auth" `
                      -allowUntrusted  `
                      -verb:sync  `
                      -enableRule:DoNotDeleteRule `
                      -disableLink:AppPoolExtension  `
                      -disableLink:ContentExtension  `
                      -disableLink:CertificateExtension  `
                      -skip:objectName=filePath,absolutePath="^(.*Web\.config|.*Environment\.config)$" `
                      -setParam:name=`"IIS Web Application Name`",value="$appName"
                      

                      然后当我尝试直接在一台服务器上运行它时,我开始收到这些错误"Unrecognized argument ...etc.... All arguments must begin with "-". "

                      在尝试了所有可能的解决方法(没有成功)之后,我发现服务器(Windows 2008 R2)上的 Powershell 是 3.0 版本,而我的笔记本电脑是 5.0。 (您可以使用“$PSVersionTable”查看版本)。

                      upgrading Powershell 升级到最新版本后,它又开始工作了。

                      【讨论】:

                        【解决方案19】:

                        如果您只需要在当前目录中运行一个文件并且不想拼出整个路径,请使用Get-Location

                        & "$(Get-Location)\example.exe" arg1 arg2 arg3
                        

                        注意开头的&amp;。间隔参数应放在引号之后。

                        【讨论】:

                          【解决方案20】:

                          所以,我遇到了类似的问题,并选择了这种方式来解决它:

                          1. 用反引号 (`) 转义引号 (") 字符
                          2. 用引号 (") 将新表达式括起来
                          3. 使用调用运算符 (&),对新字符串发出命令 invoke-expression

                          示例解决方案:

                          & { 调用表达式 "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe -verb:sync -source:dbfullsql=`"Data Source=mysource;Integrated Security=false;User ID=sa; Pwd=sapass!;Database=mydb;`" -dest:dbfullsql=`"Data Source=.\mydestsource;Integrated Security=false;用户 ID=sa;Pwd=sapass!;Database=mydb;`",computername=10.10 .10.10,username=administrator,password=adminpass`"" }

                          【讨论】:

                            【解决方案21】:

                            为了将使用 exiftool.exe 的批处理脚本传输到 powershell 脚本,我不得不为命令提供 '-s、"-s 甚至 ${Filename},另一方面,在这些参数中填写变量。

                            首先:使用“echochars”的替代方法非常棒。它清楚地显示了分组为单个参数的内容以及最终作为下一个参数的内容。

                            在 powershell 中,它类似于 perl(和 unix 脚本):使用的引号有其含义。

                            • “-s”之间的字符串。该字符串将被解释(填充变量)
                            • '-s 之间的字符串。该字符串不会被解释(或非常有限)
                            • 转义字符是`(反引号)。下一个字符失去了它的特殊含义。可与 unix/linux/perl 上的 \(回击)相媲美。

                            一些例子:

                            ${ExifArgs} += "-if `"`${FileName} !~ /desktop.ini/i`""
                            ${ExifArgs} += '-dateFormat "%Y\%Y%m\%Y%m%d_%H%M%S"'
                            ${ExifArgs} += ('"' + "-FileName<${NewFotos}\${SourceName}\" + '${DateTimeOriginal}_${ImageWidth}x${ImageHeight}_${Model;s/ //g}_${FileName;s/^.*([0-9]{4})[^0-9].*$/\1/}.%e' + '"')
                            

                            使用上述方法调用 echoargs 会产生下一个输出(为了隐私,数字被黑了):

                            Arg 11 is <-if>
                            Arg 12 is <${FileName} !~ /desktop.ini/i>
                            Arg 13 is <-dateFormat>
                            Arg 14 is <%Y\%Y%m\%Y%m%d_%H%M%S>
                            Arg 15 is <-FileName<D:\Pictures\NewFotos\${DateTimeOriginal}_${ImageWidth}x${ImageHeight}_${Model;s/ //g}_${FileName;s/^.*([0-9]{4})[^0-9].*$/\1/}.%e>
                            

                            看看第一行如何产生 arg 11 和 12:外部的 "-s 被移除以将整行存储在数组中。内部的 "-s,由 `-s 引用是为了将参数保持在一起(而 -if 是前一个参数)

                            第二个显示 arg 13 和 14:在 '-s 之间使用 "-s。无需使用 `-s 进行转义。

                            在最后一行(产生 arg 15):单个字符串是通过使用 powershell ()-s 和 +-s 将几个字符串连接到单个字符串来构造的。它使用 " 和 ' 分隔的字符串来让 som ${}-s 由 powershell 填充,一些用于 exiftool。 是的,一些 powershell 特殊字符被转换到 archuments 中。

                            【讨论】:

                              猜你喜欢
                              • 1970-01-01
                              • 2019-04-17
                              • 2013-04-02
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              相关资源
                              最近更新 更多