[英]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}
}
even though I made it a one-liner, It still won't work.即使我把它做成了单线,它仍然行不通。 the result is a new PowerShell window opening for a split second and closing.
结果是一个新的 PowerShell window 打开瞬间关闭。
how can I make it work?我怎样才能让它工作?
I studied the Argumentlist but couldn't find a way.我研究了Argumentlist但找不到方法。
This looks like a "losing the doublequotes problem".这看起来像是“丢失双引号问题”。
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.
Swap the single and doublequotes.交换单引号和双引号。 Not that start-process is needed.
不需要启动过程。 See also PowerShell stripping double quotes from command line arguments
另见PowerShell 从命令行剥离双引号 arguments
Start-Process -FilePath "PowerShell.exe" -ArgumentList "if((get-WindowsOptionalFeature -Online -FeatureName SmbDirect).state -eq 'disabled'){Enable-WindowsOptionalFeature -Online -FeatureName SmbDirect -norestart}"
tl;dr tl;博士
To make your command work, escaped the embedded "
chars in your -ArgumentList
argument as \"
.为了使您的命令正常工作,请将
-ArgumentList
参数中嵌入的"
字符转义为\"
。
'
chars escaped as ''
, or use "..."
for the outer quoting, in which case you can use '
as-is - but note that this bears the risk of up-front expansion of variable references and expressions, unless you escape $
instances as `$
.'
转义为''
的字符,或使用"..."
作为外部引号,在这种情况下,您可以按原样使用'
- 但请注意,这具有预先扩展变量引用的风险,并且表达式,除非你将$
实例转义为`$
。 However, Start-Process
may not be the best way to invoke your command ;但是,
Start-Process
可能不是调用命令的最佳方式; if synchronous invocation with output to the caller's console is desired / acceptable, use a script block to pass your command as-is (works from inside PowerShell only):如果需要/可以接受与 output同步调用到调用者的控制台,请使用脚本块按原样传递命令(仅在 PowerShell内部工作):
PowerShell.exe { if((get-WindowsOptionalFeature -Online -FeatureName SmbDirect).state -eq "disabled"){Enable-WindowsOptionalFeature -Online -FeatureName SmbDirect -norestart} }
js2010's answer provides effective solutions, but let me try to provide a systematic overview of the issues involved , to avoid potential misconceptions: js2010的回答提供了有效的解决方案,但让我尝试对所涉及的问题进行系统的概述,以避免潜在的误解:
Calling powershell.exe
, the Windows PowerShell CLI (or its PowerShell (Core) equivalent, pwsh
, from PowerShell is rarely necessary .很少需要从 PowerShell调用
powershell.exe
、Windows PowerShell CLI(或其PowerShell(核心)等价物pwsh
) 。
As with any external program , you have two basic invocation choices :与任何外部程序一样,您有两个基本的调用选择:
Direct invocation (possibly via &
, the call operator , which is situationally required for syntactic reasons ).直接调用(可能通过
&
, 调用运算符,出于句法原因在某些情况下是必需的)。
Direct invocation is usually the right approach, as it executes the program synchronously , with the program's output streams connected to PowerShell's, which by default displays them in the caller's console .直接调用通常是正确的方法,因为它同步执行程序,程序的 output 流连接到 PowerShell 的,默认情况下将它们显示在调用者的控制台中。
From inside PowerShell , irrespective of whether you're calling the respective other edition on Windows, using a script block ( {... }
) is the best choice - see this answer .从PowerShell 内部,无论您是否在 Windows 上调用相应的其他版本,使用脚本块 (
{... }
) 是最佳选择 - 请参阅此答案。
Invocation via Start-Process
, which by default executes asynchronously , in a new window , and is therefore only needed in special circumstances .通过
Start-Process
调用,默认情况下在新的 window中异步执行,因此仅在特殊情况下才需要。
Start-Process
is and isn't appropriate.Start-Process
是合适的和不合适的指南。 The fundamental problem with your own approach is that any "
characters in the -ArgumentList
argument must be escaped as \"
:您自己的方法的根本问题是
-ArgumentList
参数中的任何"
字符都必须转义为\"
:
Passing a piece of PowerShell code to a PowerShell CLI's -Command
( -c
) parameter ( by default with powershell.exe
only, explicitly with pwsh
) employs two parsing passes :将一段 PowerShell 代码传递给 PowerShell CLI 的
-Command
( -c
) 参数(默认情况下仅使用powershell.exe
,显式使用pwsh
)使用两个解析过程:
In short: unescaped "
chars. are stripped during command-line parsing , and only then are the argument(s) interpreted as PowerShell code .简而言之:未转义的
"
字符。在命令行解析期间被剥离,然后参数才被解释为 PowerShell 代码。
Any "
characters you want to be part of the PowerShell code to evaluate , must be escaped .任何您希望成为PowerShell 代码一部分的
"
都必须进行转义。
'...'
quoting, if possible, is a way to avoid this need.'...'
引号是避免这种需要的一种方法。\"
as an escaped "
, but when calling from cmd.exe
, different forms are needed in edge cases - see this answer . \"
识别为转义的"
,但是当从cmd.exe
调用时,在边缘情况下需要不同的 forms - 请参阅此答案。 When using Start-Process
with a single-string -ArgumentList
argument:将
Start-Process
与单字符串-ArgumentList
参数一起使用时:
\"
to escape "
chars. \"
转义"
字符。 is enough. When using direct invocation :使用直接调用时:
It is reasonable to expect PowerShell to automatically escape embedded "
characters, such as when calling powershell.exe '"hi"'
期望PowerShell自动转义嵌入的
"
字符是合理的,例如调用powershell.exe '"hi"'
时
In PowerShell 7.3.0 and 7.3.1 , specifically, it does work as expected by default , however, a future update will likely require opt-in - see GitHub issue #18694在PowerShell 7.3.0 和 7.3.1中,具体来说,默认情况下它确实按预期工作,但是,未来的更新可能需要选择加入- 请参阅GitHub 问题 #18694
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.