每个参数都被去除其封闭的 ..."(如果存在).剥离的参数用空格连接.生成的单个字符串然后作为 PowerShell 代码执行.也就是说,PowerShell 尝试使用上述命令执行具有以下逐字内容的字符串:&C:Program FilesFolderfile.ps1 -verbose:$True -restart如您所见,包含空格的脚本文件路径缺少必要的引用.您有几个选项可以在脚本路径周围提供必要的引用:如果您知道您的脚本路径不包含'字符,请使用embedded '...' 引用:powershell -Command "&'C:Program FilesFolderfile.ps1' -Verbose:$true -Restart只有一对外部 " 字符,您不必担心 cmd.exe 会在前面 无意中解释您的参数em>,在他们到达 PowerShell 之前.您可以在这种情况下也可以省略外部引用,但这使得未引用参数容易被cmd.exe(虽然在这种情况下很好),并注意 ' 在 cmd.exe 中没有特殊含义,所以 PowerShell 风格的 '...' 字符串被 cmd.exe 视为未加引号:rem # 有效,但通常不如上面的健壮.powershell -Command ^&'C:Program FilesFolderfile.ps1' -Verbose:$true -Restart如果您想确保带有嵌入 ' 字符的偶数路径.正常工作:使用嵌入的双引用,将"转义为"(原文如此):powershell -Command "&C:Program FilesFolderfile.ps1"-详细:$true -重新启动"不幸的是,这再次使 " 实例之间的字符串受到 cmd.exe 可能不需要的解释.您可以通过使用 "" (sic) 来解决此问题,但这会使 "" 实例之间的字符串受 空格归一化:即将一行中的多个空格折叠成一个.在 Windows PowerShell 中,您可以通过使用 "^""(原文如此)来避免这种情况,但请注意,在 PowerShell Core 您将获得与 "" 相同的行为.rem # Windows PowerShell 中最强大的形式.rem # 仍然受 PowerShell Core 中的空白规范化约束.powershell -Command "&"^""C:Program FilesFolderfile.ps1"^""-详细:$true -重新启动"I have a script that sits in Program Files folder and accepts arguments: verbose and restartRunning it from its folder works perfectly:powershell ./<file.ps1> -verbose:$True -restartTrying to run it using full path is where I have issues:powershell & "C:Program FilesFolder<file.ps1> -verbose:$True -restart"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.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? 解决方案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 .However, when using PowerShell's CLI it is simpler to use -File (-f) to execute a script, which makes & unnecessary and simplifies quoting:powershell -File "C:Program FilesFolderfile.ps1" -Verbose -RestartWhen 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.Use -Command (-c) only if you need to pass a snippet of PowerShell code and/or arguments script-file arguments must be interpreted as they would from inside PowerShell:powershell -Command "& 'C:Program FilesFolderfile.ps1' -Verbose:$true -Restart"Note: -Command is notably needed in order to be able to pass arrays as script-file arguments; see this answer.The crucial improvements to your attempt are:& is placed inside "...", which prevents cmd.exe from interpreting it itself, before PowerShell sees it.The script path is enclosed in embedded quoting ('...'), so that PowerShell sees the path as quoted.Note:-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. See this answer for a comprehensive overview of the two PowerShell CLIs.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.As for what you tried: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.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.That is, your command is the equivalent of the following 2 commands, executed in sequence:powershell"C:Program FilesFolderfile.ps1 -verbose:$True -restart"The 1st command opens an interactive PowerShell session.Only after you manually exit it does the 2nd command get executed.Note that your specific symptom suggests that you used only "C:Program FilesFolder<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.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 workpowershell ^& "C:Program FilesFolderfile.ps1 -verbose:$True -restart"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: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.That is, with the above command PowerShell tried to execute a string with the following verbatim content:& C:Program FilesFolderfile.ps1 -verbose:$True -restartAs 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:If you know that your script path does not contain ' chars, use embedded '...' quoting:powershell -Command "& 'C:Program FilesFolderfile.ps1' -Verbose:$true -Restart"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.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 FilesFolderfile.ps1' -Verbose:$true -RestartIf you want to ensure that even paths with embedded ' chars. work properly:Use embedded double-quoting, with the " escaped as " (sic):powershell -Command "& "C:Program FilesFolderfile.ps1" -Verbose:$true -Restart"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.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 FilesFolderfile.ps1"^"" -Verbose:$true -Restart" 这篇关于使用命令行中的完整路径和参数运行 powershell 命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-04 13:59
查看更多