powershell - 在命令行中使用完整路径和参数运行Powershell命令

标签 powershell command-line command-prompt

我有一个脚本,它位于Program Files文件夹中并接受参数:verboserestart从其文件夹运行它可以完美运行:

powershell ./<file.ps1> -verbose:$True -restart

尝试使用完整路径运行它是我遇到的问题:
powershell & "C:\Program Files\Folder\<file.ps1> -verbose:$True -restart"

上面的命令不会运行脚本;而是打开PS命令提示符,并在退出时在记事本中打开脚本。
我也尝试将每个变量放在单独的引号中,但效果不佳。

我通过使用progra~1而不是Program Files找到了一种解决方法,但我想以适当的方式解决此问题。
我想念什么?

最佳答案

顺便说一句:可以通过在脚本路径中使用环境变量$env:ProgramFiles而不是文字"C:\Program Files\..."来避免该问题的与报价相关的部分,这会将命令简化为:powershell "& $env:ProgramFiles\Folder\file.ps1 -verbose:$True -restart"

的确,为了执行在PowerShell中带有嵌入式空格的文字路径引用的脚本,必须将这些路径加引号并将引用的路径传递给&.

但是,当使用PowerShell's CLI时,使用-File来执行脚本更加容易,这使得&不再需要并简化了引用:

powershell -File "C:\Program Files\Folder\file.ps1" -Verbose -Restart

从外部调用PowerShell时,从字面上接受
(如果删除了语法-File(如果存在)之后),则按字面意义接受"..."后面的参数-如果您从PowerShell内部运行命令,它们的方式将不会被解释。例如,从PowerShell外部调用时,powershell -File script.ps1 $env:USERNAME会将字符串$env:USERNAME逐字传递给script.ps1而不是扩展它-如果需要,请使用-Command

仅在需要传递PowerShell代码片段时使用-Command:
powershell -Command "& 'C:\Program Files\Folder\file.ps1' -Verbose:$true -Restart"

您尝试的关键改进是:
  • &放置在"..."内,这可防止cmd.exe在PowerShell看到它之前解释它本身。
  • 脚本路径包含在嵌入式引号('...')中,以便PowerShell将路径视为引用的路径。

  • 注意:
  • -Command是为了清楚起见;在Windows PowerShell中,可以将其省略(如您所做的那样),因为它是默认参数。但是请注意,在PowerShell Core中,默认值现在为-File
  • 严格来说,您不需要将所有内容都作为一个"..."字符串传递,但是从概念上讲,这种方式更清晰。

  • 有关详情,请参见下文。

    另请注意,-File-Command
    之间的设置(过程)退出代码的方式有所不同-参见this answer

    至于您尝试了什么:

    Above command doesn't run the script; Instead it's opening the PS command prompt and when exiting it, it opens the script in notepad.



    这意味着您是从cmd.exe
    (从命令提示符或批处理文件)中调用的,其中和未包含在&中的"..."具有特殊含义:它是命令序列运算符。

    也就是说,您的命令等效于以下两个命令,依次执行:
    powershell
    "C:\Program Files\Folder\file.ps1 -verbose:$True -restart"
    

    第一个命令打开一个交互式PowerShell session 。
    仅在手动退出后,第二条命令才会执行。

    请注意,您的特定症状建议您仅使用"C:\Program Files\Folder\<file.ps1>"(不带参数)作为第二个命令,该命令的确会打开该脚本文件作为文档进行编辑。

    使用参数,将整个双引号字符串解释为文件名,您将获得通常的... is not recognized as an internal or external command, operable program or batch file.
    为了使能够将cmd.exe传递给被调用的命令,必须用&括起来,或者在这样的字符串之外,以"..." 进行转义。

    但是,仅解决一个问题还不够:
    rem # !! Still doesn't work
    powershell ^& "C:\Program Files\Folder\file.ps1 -verbose:$True -restart"
    

    另一个问题是,当您使用^& CLI参数时(隐含在您的情况下),PowerShell使用以下逻辑来处理参数:
  • 如果有每个参数,将除去其封闭的-Command
  • 剥离的参数由空格连接。
  • 然后将生成的单个字符串作为PowerShell代码执行。

  • 也就是说,通过上述命令,PowerShell尝试执行具有以下逐字内容的字符串:
    & C:\Program Files\Folder\file.ps1 -verbose:$True -restart
    

    如您所见,脚本文件路径(包含空格)缺少必需的引号。

    您有几个选项可提供有关脚本路径的必要报价:

    如果您知道您的脚本路径不包含"..." chars ,请使用嵌入式'引用:
    powershell -Command "& 'C:\Program Files\Folder\file.ps1' -Verbose:$true -Restart"
    

    仅需一对外部'...'字符,您就不必担心"在到达PowerShell之前无意间先解释了您的参数。

    在这种情况下,您也可以省略外部引号,但这会使未加引号的参数容易受到cmd.exe的不必要解释(尽管在这种情况下很好),并请注意cmd.exe'中没有特殊含义,因此是PowerShell样式的cmd.exe字符串被'...'视为未引用:
    rem # Works, but generally less robust than the above.
    powershell -Command ^& 'C:\Program Files\Folder\file.ps1' -Verbose:$true -Restart
    

    如果要确保包含嵌入式cmd.exe的偶数路径为char。可以正常工作:

    使用嵌入式双引号,将'转义为"(sic):
    powershell -Command "& \"C:\Program Files\Folder\file.ps1\" -Verbose:$true -Restart"
    

    不幸的是,这再次使得\"实例之间的字符串可能受到\"可能有害的解释。

    您可以改为使用cmd.exe(sic)来解决此问题,但这会使\""实例之间的字符串经受空格标准化:即,一行中的多个空格被折叠为一个。

    在Windows PowerShell中,可以通过使用\""(sic)避免这种情况,但是请注意,在PowerShell Core中,您将获得与oj​​it_code相同的行为。
    rem # The most robust form in Windows PowerShell.
    rem # Still subject to whitespace normalization in PowerShell Core.
    powershell -Command "& "^""C:\Program Files\Folder\file.ps1"^"" -Verbose:$true -Restart"
    

    关于powershell - 在命令行中使用完整路径和参数运行Powershell命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57441095/

    相关文章:

    windows - 如何使批处理文件删除它自己的目录?

    macos - 如何抑制(或自定义)Mac 终端 shell 提示

    Powershell cmd 跟踪目录文件

    powershell - 不等待用户输入的远程 powershell 和提示

    powershell - 如何处理PowerShell中的反斜杠字符-替换字符串操作?

    python - 如何防止 docopt 吞下一个选项?

    linux - 帮助使用 PDFKit 和 Rails 应用程序

    Powershell 应用程序池设置周期性重启语法

    c++ - 将任何类型的文件转换为带有 c 字符串的文件

    visual-studio - 在Visual Studio中执行dos命令的交互式窗口