powershell - 使用命令行中的完整路径和参数运行 powershell 命令
问题描述
我有一个位于Program Files
文件夹中并接受参数的脚本:
从其文件夹中运行它可以完美运行verbose
:restart
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 的 CLI时,使用( ) 来执行脚本会更简单-File
-f
,这样就&
不需要并简化了引用:
powershell -File "C:\Program Files\Folder\file.ps1" -Verbose -Restart
当从外部调用 PowerShell 时,后面的参数将按字面意思-File
获取(在删除 syntactic 后"..."
,如果存在的话) -如果您从PowerShell内部运行命令,它们不会被解释为它们的方式;例如,当从PowerShell外部调用时,会将字符串逐字传递给 而不是扩展它- 如果需要,请使用.powershell -File script.ps1 $env:USERNAME
$env:USERNAME
script.ps1
-Command
仅当您需要传递一段 PowerShell 代码和/或参数时才使用-Command
( )必须像从PowerShell内部-c
那样解释脚本文件参数:
powershell -Command "& 'C:\Program Files\Folder\file.ps1' -Verbose:$true -Restart"
注意:-Command
为了能够将数组作为脚本文件参数传递,特别需要它;看到这个答案。
您的尝试的关键改进是:
&
被放置在里面"..."
,这样可以防止在PowerShell 看到它之前自行cmd.exe
解释它。脚本路径包含在嵌入的引号 (
'...'
) 中,以便 PowerShell 将路径视为引号。
笔记:
-Command
用于清楚起见;在Windows PowerShell中,它可以被省略(就像你所做的那样),因为它是默认参数;但是请注意,在 PowerShell Core中,默认值为 now-File
。有关两个 PowerShell CLI 的全面概述,请参阅此答案。您并不严格需要将所有内容都作为一个
"..."
字符串传递,但这种方式在概念上更清晰。
详情见下文。
另请注意,(进程)退出代码-File
的设置方式在和之间有所不同-Command
- 请参阅此答案。
至于你尝试了什么:
上面的命令不运行脚本;相反,它打开 PS 命令提示符,退出它时,它会在记事本中打开脚本。
这意味着您是从cmd.exe
(从命令提示符或批处理文件)调用的,其中未&
包含的"..."
具有特殊含义:它是命令序列运算符。
也就是说,您的命令相当于以下2 个命令,按顺序执行:
powershell
"C:\Program Files\Folder\file.ps1 -verbose:$True -restart"
第一个命令打开一个交互式PowerShell 会话。只有在您手动退出后,才会执行第二个命令。
请注意,您的具体症状表明您只使用"C:\Program Files\Folder\<file.ps1>"
了第二个命令,没有参数,它确实会将该脚本文件作为文档打开,以进行编辑。
使用参数,整个双引号字符串被解释为文件名,你会得到通常的... is not recognized as an internal or external command, operable program or batch file.
为了将cmd.exe
a 传递&
给正在调用的命令,它必须包含在 中"..."
,或者在这样的字符串之外,转义为^&
。
然而,即使解决一个问题是不够的:
rem # !! Still doesn't work
powershell ^& "C:\Program Files\Folder\file.ps1 -verbose:$True -restart"
另一个问题是,当您使用-Command
CLI 参数时, PowerShell使用以下逻辑来处理参数:
"..."
如果存在,每个参数都将被剥离。- 剥离的参数与空格连接。
- 然后将生成的单个字符串作为 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
(尽管在这种情况下很好),并注意在'
中没有特殊含义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
如果您想确保包含嵌入'
字符的路径。正常工作:
使用嵌入式双引号,"
转义为\"
(原文如此):
powershell -Command "& \"C:\Program Files\Folder\file.ps1\" -Verbose:$true -Restart"
不幸的是,这再次使\"
实例之间的字符串受到潜在有害解释的影响cmd.exe
。
您可以通过使用 (sic) 来解决此问题\""
,但这会使\""
实例之间的字符串受到空白规范化:也就是说,一行中的多个空格被折叠成一个。
在Windows PowerShell中,您可以通过使用"^""
(sic) 来避免这种情况,但请注意,在 PowerShell Core中,您将获得与使用\""
.
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"
推荐阅读
- python - 使函数变量静态化的Python方法
- c# - 运算符“/”不能应用于“double”和“System.Windows.Forms.TextBox”类型的操作数
- java - NoSuchBeanDefinitionException:没有符合条件的 bean 类型(存储库)
- javascript - 如何在拖放 d3 v4 中获取目标元素?
- directx - 如何将 nvEncode 输入缓冲区复制到 Direct3d11 纹理?
- python - 如何用两个“for”枚举列表理解?
- c# - 我无法删除注册表子项
- javascript - 循环道具的最佳位置是什么
- scala - 如何在波光粼粼的水域 h2oflow UI 中绘制数据探索图?
- php - 获取数组中最小的变量