繁体   English   中英

如何将 If 语句传递给 PowerShell 的启动进程的参数列表?

[英]How to pass an If statement to the Argumentlist of Start-process for PowerShell?

if ($PSVersionTable.PSVersion.Major,$PSVersionTable.PSVersion.Minor -join "." -gt 5.1) {   
    
Start-Process -FilePath "PowerShell.exe" -ArgumentList 'if((get-WindowsOptionalFeature -Online -FeatureName SmbDirect).state -eq "disabled"){Enable-WindowsOptionalFeature -Online -FeatureName SmbDirect -norestart}'
}

else
{
if((get-WindowsOptionalFeature -Online -FeatureName SmbDirect).state -eq "disabled"){Enable-WindowsOptionalFeature -Online -FeatureName SmbDirect -norestart}
}

即使我把它做成了单线,它仍然行不通。 结果是一个新的 PowerShell window 打开瞬间关闭。

我怎样才能让它工作?

我研究了Argumentlist但找不到方法。

这看起来像是“丢失双引号问题”。

powershell '"a"'

a : The term 'a' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and
try again.

交换单引号和双引号。 不需要启动过程。 另见PowerShell 从命令行剥离双引号 arguments

Start-Process -FilePath "PowerShell.exe" -ArgumentList "if((get-WindowsOptionalFeature -Online -FeatureName SmbDirect).state -eq 'disabled'){Enable-WindowsOptionalFeature -Online -FeatureName SmbDirect -norestart}"

tl;博士

  • 为了使您的命令正常工作,请将-ArgumentList参数中嵌入的"字符转义为\"

    • 或者,使用嵌入'转义为''的字符,或使用"..."作为外部引号,在这种情况下,您可以按原样使用' - 但请注意,这具有预先扩展变量引用的风险,并且表达式,除非你将$实例转义为`$
  • 但是, Start-Process可能不是调用命令的最佳方式 如果需要/可以接受与 output同步调用到调用者的控制台,请使用脚本块按原样传递命令(仅在 PowerShell内部工作):

     PowerShell.exe { if((get-WindowsOptionalFeature -Online -FeatureName SmbDirect).state -eq "disabled"){Enable-WindowsOptionalFeature -Online -FeatureName SmbDirect -norestart} }

背景资料:

js2010的回答提供了有效的解决方案,但让我尝试对所涉及的问题进行系统的概述,以避免潜在的误解:

  • 很少需要从 PowerShell调用powershell.exe 、Windows PowerShell CLI(或其PowerShell(核心)等价物pwsh

  • 与任何外部程序一样,您有两个基本的调用选择

    • 直接调用(可能通过&调用运算符出于句法原因在某些情况下是必需的)。

      • 直接调用通常是正确的方法,因为它同步执行程序,程序的 output 流连接到 PowerShell 的,默认情况下将它们显示在调用者的控制台中。

      • PowerShell 内部,无论您是否在 Windows 上调用相应的其他版本,使用脚本块 ( {... } ) 是最佳选择 - 请参阅此答案

    • 通过Start-Process调用,默认情况下在新的 window异步执行,因此仅在特殊情况下才需要。


您自己的方法的根本问题是-ArgumentList参数中的任何"字符必须转义为\"

  • 将一段 PowerShell 代码传递给 PowerShell CLI 的-Command ( -c ) 参数默认情况下仅使用powershell.exe显式使用pwsh )使用两个解析过程:

    • 简而言之:转义"字符。在命令行解析期间被剥离,然后参数才被解释为 PowerShell 代码

    • 任何您希望成为PowerShell 代码一部分的"都必须进行转义

      • 如果可能,使用嵌入式'...'引号是避免这种需要的一种方法。
      • PowerShell 本身,在两个版本中,始终\"识别为转义的" ,但是当cmd.exe调用时,在边缘情况下需要不同的 forms - 请参阅此答案
  • Start-Process单字符串-ArgumentList参数一起使用时:

    • (可能由 PowerShell 预处理)字符串的逐字值成为在幕后构建的原始进程命令行的一部分,因此使用\"转义"字符。 足够。
  • 使用直接调用时

    • 期望PowerShell自动转义嵌入的"字符是合理的,例如调用powershell.exe '"hi"'

      • 但是,由于一直存在到 v7.2.x 的错误,这无法按预期工作- 请参阅此答案
    • PowerShell 7.3.0 和 7.3.1中,具体来说,默认情况下确实按预期工作,但是,未来的更新可能需要选择加入- 请参阅GitHub 问题 #18694

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM