使用命令行中的完整路径和参数运行powershell命令

使用命令行中的完整路径和参数运行powershell命令,powershell,command-line,command-prompt,Powershell,Command Line,Command Prompt,我有一个脚本,它位于ProgramFiles文件夹中并接受参数:verbose和restart 从其文件夹中运行它非常有效: powershell ./<file.ps1> -verbose:$True -restart 尝试使用完整路径运行它是我遇到问题的地方: powershell & "C:\Program Files\Folder\<file.ps1> -verbose:$True -restart" 上面的命令不运行脚本;相反,它会打开PS命令提示符

我有一个脚本,它位于ProgramFiles文件夹中并接受参数:verbose和restart 从其文件夹中运行它非常有效:

powershell ./<file.ps1> -verbose:$True -restart
尝试使用完整路径运行它是我遇到问题的地方:

powershell & "C:\Program Files\Folder\<file.ps1> -verbose:$True -restart"
上面的命令不运行脚本;相反,它会打开PS命令提示符,退出时会在记事本中打开脚本。 我还尝试将每个变量放在一个单独的引号中,但效果并不理想

我找到了一个解决办法,用progra~1代替程序文件,但我想用正确的方法解决这个问题。 我遗漏了什么?

作为旁白:使用环境变量$env:ProgramFiles而不是文字C:\Program Files\,可以避免问题的引用相关部分。。。在脚本路径中,这会将命令简化为: powershell&$env:ProgramFiles\Folder\file.ps1-详细:$True-重新启动

实际上,为了执行PowerShell中嵌入空格的文本路径引用的脚本,必须引用这些路径,并且引用的路径必须传递给&或

但是,在使用时,使用-File执行脚本更简单,这使得“不必要”并简化了引用:

powershell -File "C:\Program Files\Folder\file.ps1" -Verbose -Restart
当从外部调用PowerShell时,-File后面的参数会在删除语法…(如果存在)后按字面理解,它们不会像从PowerShell内部运行命令那样被解释;e、 例如,当从PowerShell外部调用时,PowerShell-File script.ps1$env:USERNAME会将字符串$env:USERNAME逐字传递给script.ps1,而不是扩展它-如果需要,请使用-Command

仅当需要传递PowerShell代码片段时才使用-Command:

您尝试的关键改进包括:

&放置在…,这会阻止cmd.exe在PowerShell看到它之前自行解释它

脚本路径包含在嵌入的引号“…”中,因此PowerShell会将该路径视为引用的路径

注:

-使用命令是为了清晰;在Windows PowerShell中,可以像您一样忽略它,因为它是默认参数;但是,请注意,在PowerShell核心中,默认值现在是-File

你不需要严格地把所有的东西都作为一个整体通过。。。字符串,但这样在概念上更清晰

详情见下文

还请注意,-File和-Command之间进程退出代码的设置方式有所不同-请参阅

至于你尝试了什么:

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

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

也就是说,您的命令相当于按顺序执行的以下两个命令:

第一个命令打开交互式PowerShell会话。 只有手动退出后,才能执行第二个命令

请注意,您的特定症状表明,您只使用了C:\Program Files\Folder\(不带参数)作为第二个命令,该命令确实会将该脚本文件作为文档打开以进行编辑

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

为了让cmd.exe将&传递给被调用的命令,它必须包含在…,或者,在这样的字符串之外,转义为^&

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

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
如您所见,包含空格的脚本文件路径缺少必要的引号

您有几个选项可以围绕脚本路径提供必要的引用:

如果您知道脚本路径不包含“字符,请使用嵌入的”…“引号:

由于只有一对外部字符,您不必担心cmd.exe会在参数到达PowerShell之前不经意地预先解释它们

在本例中,您也可以省略外部引号,但这会使未加引号的参数容易受到cmd.exe的不必要解释的影响,尽管在本例中没有问题,请注意“在cmd.exe中没有特殊含义,因此PowerShell样式”…“字符串被cmd.exe视为未加引号:

如果您想确保即使是带有嵌入字符的路径。工作正常:

使用嵌入式双- 引用,转义为\sic:

不幸的是,这再次使\实例之间的字符串受到cmd.exe可能不需要的解释

您可以使用\sic来解决这个问题,但这会使\instances之间的字符串受到空白规范化的影响:即,一行中的多个空格被折叠成一个

在Windows PowerShell中,您可以通过使用^sic来避免这种情况,但请注意,在PowerShell Core中,您将获得与\相同的行为

rem # !! Still doesn't work
powershell ^& "C:\Program Files\Folder\file.ps1 -verbose:$True -restart"
& C:\Program Files\Folder\file.ps1 -verbose:$True -restart
powershell -Command "& 'C:\Program Files\Folder\file.ps1' -Verbose:$true -Restart"
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"
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"