在命令行中使用完整路径和参数运行Powershell命令 [英] Running a powershell command using full path and arguments from command line

查看:93
本文介绍了在命令行中使用完整路径和参数运行Powershell命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个脚本位于 Program Files 文件夹中,并接受参数: verbose 重新启动
从其文件夹中运行非常正常:

I have a script that sits in Program Files folder and accepts arguments: verbose and restart Running it from its folder works perfectly:

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

尝试使用完整路径运行它是我遇到的问题:

Trying to run it using full path is where I have issues:

powershell & "C:\Program Files\Folder\<file.ps1> -verbose:$True -restart"

以上命令不运行脚本;相反,它打开PS命令提示符,并在退出时在记事本中打开脚本。

我还尝试将每个变量放在单独的引号中,但效果不佳。

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.
I also tried to put each variable in a separate quote but that didn't work as well.

我找到了一种解决方法,方法是使用 progra〜1 代替 Program Files 但是我想以正确的方式解决问题。


我缺少了什么?

I found a workaround by using progra~1 instead of Program Files but I'd like to solve the issue the proper way.

What am I missing?

推荐答案

顺便说一句:通过使用环境变量 $ env:ProgramFiles 而不是文字<$ c $,可以避免与报价有关的部分c> C:\Program Files\ ... 可以将命令简化为:

powershell & $ env:ProgramFiles\Folder\file.ps1 -verbose:$ True -restart

As an aside: The quoting-related part of the problem could have been avoided by using environment variable $env:ProgramFiles instead of literal "C:\Program Files\..." in the script path, which would have simplified the command to:
powershell "& $env:ProgramFiles\Folder\file.ps1 -verbose:$True -restart"

实际上,要在PowerShell中执行带有嵌入空格的文字路径所引用的脚本,必须在这些路径中加上 和引用的路径必须传递到&

Indeed, in order to execute scripts referenced by literal paths with embedded spaces in PowerShell, those paths must be quoted and the quoted path must be passed to & or .

但是,使用 PowerShell的CLI 使用 -File 执行脚本更简单,这使得& 不必要,并简化了引用:

However, when using PowerShell's CLI it is simpler to use -File to execute a script, which makes & unnecessary and simplifies quoting:

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

从PowerShell调用时外部,在文件之后的参数是按字面意思 的(在删除语法<$ c $之后c> ... (如果存在)-如果您从 inside PowerShell中运行命令,它们将被解释为;例如,当从外部 PowerShell进行调用时, powershell -File script.ps1 $ env:USERNAME 将传递字符串 $ env: USERNAME verbatim 改为 script.ps1 而不是扩展它-如果需要,请使用 -Command

When PowerShell is called from the outside, arguments that follow -File are taken literally (after removing syntactic "...", if present) - they are not interpreted the way they would be if you ran the command from inside PowerShell; e.g., when calling from outside PowerShell, powershell -File script.ps1 $env:USERNAME would pass string $env:USERNAME verbatim to script.ps1 rather than expanding it - if you need that, use -Command.

仅在需要通过时使用 -Command PowerShell代码片段

Use -Command only if you need to pass a snippet of PowerShell code:

powershell -Command "& 'C:\Program Files\Folder\file.ps1' -Verbose:$true -Restart"


  • & ... 内,这可以防止 cmd.exe 解释为本身之前 PowerShell看到它。

  • & is placed inside "...", which prevents cmd.exe from interpreting it itself, before PowerShell sees it.

脚本路径包含在嵌入式引号('...'),以便PowerShell看到引用的路径。

The script path is enclosed in embedded quoting ('...'), so that PowerShell sees the path as quoted.

注意:


  • -命令是为了清楚起见;在 Windows PowerShell 中,可以将其省略(如您所做的那样),因为它是 default 参数。但是请注意,在PowerShell Core 中,默认值现在为-文件

  • -Command is used for clarity; in Windows PowerShell, it can be omitted (as you did), because it is the default parameter; note, however, that in PowerShell Core the default is now -File.

您严格不需要将所有内容都传递为一个 ... 字符串,但是从概念上讲,这种方式更清晰。 / p>

You don't strictly need to pass everything as one "..." string, but it is conceptually clearer that way.

有关详细信息,请参见下文。

See below for details.

还请注意(过程)退出代码的设置方式在-文件-命令 -请参见此答案

Also note that how the (process) exit code is set differs between -File and -Command - see this answer.

关于您尝试过的操作


上面的命令没有运行脚本;而是打开PS命令提示符,并在退出时在记事本中打开脚本。

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 重新调用(从命令提示符或批处理文件),其中一个& ... 中没有包含的c $ c>具有特殊含义:它是命令排序运算符。

This implies that you're calling from cmd.exe (from the Command Prompt or a batch file), where an & not enclosed in "..." has special meaning: it is the command-sequencing operator.

也就是说,您的命令等效于以下 2 命令,依次执行

That is, your command is the equivalent of the following 2 commands, executed in sequence:

powershell
"C:\Program Files\Folder\file.ps1 -verbose:$True -restart"

第一个命令打开一个 interactive PowerShell会话。
只有手动退出后,第二条命令才会执行。

The 1st command opens an interactive PowerShell session. Only after you manually exit it does the 2nd command get executed.

请注意,您的特定症状表明您仅使用了 C :\Program Files\Folder\< file.ps1> ,不带参数,作为第二个命令,该命令确实会将该脚本文件作为 document 打开,对于 editing

Note that your specific symptom suggests that you used only "C:\Program Files\Folder\<file.ps1>", without arguments, as the 2nd command, which would indeed open that script file as a document, for editing.

使用参数,整个双引号字符串将解释为文件名,并且您将得到通常的 ...未被识别为内部或外部命令,
可操作程序或批处理文件。

With the arguments, the entire double-quoted string is interpreted as a filename, and you'll get the usual ... is not recognized as an internal or external command, operable program or batch file.

为了 cmd.exe 通过& 通过到要调用的命令,它必须放在 ... 中,或者在这样的字符串之外,转义为 ^&

In order for cmd.exe to pass a & through to a command being invoked, it must either be enclosed in "...", or, outside of such a string, escaped as ^&.

但是,即使解决一个一个问题也是不够的:

However, even fixing that one problem isn't enough:

rem # !! Still doesn't work
powershell ^& "C:\Program Files\Folder\file.ps1 -verbose:$True -restart"

另一个问题是,当您使用 -Command CLI参数(在您的情况下暗示 )时,PowerShell使用以下逻辑来处理参数:

The other problem is that when you use the -Command CLI parameter, which is implied in your case, PowerShell uses the following logic to process the arguments:


  • 每个参数都被删除了其封闭的 ... ,如果存在的话。

  • 已剥离的参数用空格连接。

  • 生成的单个字符串先 then 作为PowerShell执行代码。

  • Each argument is stripped of its enclosing "...", if present.
  • The stripped arguments are concatenated with spaces.
  • The resulting single string is then executed as PowerShell code.

也就是说,PowerShell尝试执行具有以下逐字内容的字符串:

That is, with the above command PowerShell tried to execute a string with the following verbatim content:

& C:\Program Files\Folder\file.ps1 -verbose:$True -restart

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

As you can see, the script file path, which contains a space, lacks the necessary quoting.

您可以通过多种方法在脚本路径周围提供必要的引号:

You have several options to provide the necessary quoting around the script path:

如果您知道您的脚本路径 not 不包含'字符,使用嵌入 '...'引用:

powershell -Command "& 'C:\Program Files\Folder\file.ps1' -Verbose:$true -Restart"

只有一个外部的 字符。,您不必担心 cmd.exe 在到达PowerShell之前无意中解释了您的参数 upfront

With only a single, outer pair of " chars., you needn't worry about cmd.exe inadvertently interpreting your arguments up front, before they reach PowerShell.

在这种情况下,您可以也省略外部引号,但这会使未引号参数容易受到的不必要解释。 cmd.exe (尽管在这种情况下还可以),但请注意' cmd.exe 中没有特殊含义,因此 cmd.exe 将PowerShell样式的'...'字符串视为未引用

You could also omit the outer quoting in this case, but that makes the unquoted arguments susceptible to unwanted interpretation by cmd.exe (though it's fine in this case), and note that ' has no special meaning in cmd.exe, so a PowerShell-style '...' string is considered unquoted by cmd.exe:

rem # Works, but generally less robust than the above.
powershell -Command ^& 'C:\Program Files\Folder\file.ps1' -Verbose:$true -Restart



< hr>

如果要确保包含嵌入式'字符的偶数路径。工作正常


If you want to ensure that even paths with embedded ' chars. work properly:

使用嵌入的 double 引号,并带有 \ (原文如此)转义:

Use embedded double-quoting, with the " escaped as \" (sic):

powershell -Command "& \"C:\Program Files\Folder\file.ps1\" -Verbose:$true -Restart"

不幸的是,这再次使 \ 实例之间的字符串受到 cmd潜在的有害解释。 exe

Unfortunately, this again makes the string between the \" instances subject to potentially unwanted interpretation by cmd.exe.

您可以通过使用 \ (原文如此)来解决此问题),但这会使 \ 实例之间的字符串受到空白规范化的约束:也就是说,一行中的多个空格被折叠

You can work around this by using \"" (sic) instead, but that makes the string between the \"" instances subject to whitespace normalization: that is, multiple spaces in a row are folded into one.

Windows PowerShell 中,可以通过使用 ^ (原文如此),但请注意,在PowerShell Core 中,您将获得与 \ 相同的行为。

In Windows PowerShell, you can avoid that by using "^"" (sic), but note that in PowerShell Core you'll get the same behavior as with \"".

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命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆